Added send and forward methods. Improved data structures.

Next: serialization of ChatLobbyItems



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-ChatLobby@4690 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2011-11-25 21:31:52 +00:00
parent 5cdc36d730
commit cd30487898
5 changed files with 152 additions and 22 deletions

View File

@ -30,6 +30,7 @@
#include <list>
#include <iostream>
#include <string>
#include <set>
#include "rstypes.h"
@ -61,7 +62,9 @@
#define RS_MSGTAGTYPE_LATER 5
#define RS_MSGTAGTYPE_USER 100
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
class MessageInfo
{
@ -140,10 +143,11 @@ class ChatInfo
class ChatLobbyInfo
{
public:
ChatLobbyId lobby_id ;
std::string display_name ;
std::list<std::string> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages.
std::list<std::string> additional_peers ; // list of non direct friend who participate. Used to display only.
ChatLobbyId lobby_id ; // unique id of the lobby
std::string nick_name ; // nickname to use for this lobby
std::set<std::string> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages.
std::set<std::string> nick_names ; // list of non direct friend who participate. Used to display only.
};
std::ostream &operator<<(std::ostream &out, const MessageInfo &info);

View File

@ -44,12 +44,14 @@ const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020;
const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040;
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080;
const uint32_t RS_CHAT_FLAG_PARTIAL_MESSAGE = 0x0100;
const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200;
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; // default is 0x01
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ; // default is 0x01
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ; // default is 0x01
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x06 ;
// for defining tags themselves and msg tags
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
@ -57,6 +59,9 @@ const uint8_t RS_PKT_SUBTYPE_MSG_TAGS = 0x04;
const uint8_t RS_PKT_SUBTYPE_MSG_SRC_TAG = 0x05;
const uint8_t RS_PKT_SUBTYPE_MSG_PARENT_TAG = 0x06;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
class RsChatItem: public RsItem
{
@ -81,9 +86,9 @@ class RsChatItem: public RsItem
class RsChatMsgItem: public RsChatItem
{
public:
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT)
{
}
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {}
RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {}
RsChatMsgItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatMsgItem() {}
@ -100,6 +105,24 @@ class RsChatMsgItem: public RsChatItem
uint32_t recvTime;
};
class RsChatLobbyMsgItem: public RsChatMsgItem
{
public:
RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_MSG) {}
RsChatLobbyMsgItem(void *data,uint32_t size) {} // deserialization /// TODO!!!
virtual ~RsChatLobbyMsgItem() {}
ChatLobbyId lobby_id ;
ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ;
/// TODO !!!
virtual bool serialise(void *data,uint32_t& size) { return true ; } // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() { return 0;} // deserialise is handled using a constructor
};
/*!
* For saving incoming and outgoing chat msgs
* @see p3ChatService

View File

@ -24,6 +24,7 @@
*/
#include "util/rsdir.h"
#include "util/rsrandom.h"
#include "retroshare/rsiface.h"
#include "pqi/pqibin.h"
#include "pqi/pqinotify.h"
@ -1138,27 +1139,113 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
//********************** Chat Lobby Stuff ***********************//
bool p3ChatService::recvLobbyChat(RsChatLobbyMsgItem *item)
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
std::cerr << "Handling ChatLobbyMsg " << std::hex << item->msg_id << ", lobby id " << item->lobby_id << ", from peer id " << item->PeerId() << std::endl;
// send upward for display
std::map<ChatLobbyId,ChatLobbyEntry>::iterator it(_chat_lobbys.find(item->lobby_id)) ;
if(it == _chat_lobbys.end())
{
std::cerr << "Chatlobby for id " << std::hex << item->lobby_id << " has no record. Dropping the msg." << std::dec << std::endl;
return false ;
}
ChatLobbyEntry& lobby(it->second) ;
// Adds the peer id to the list of friend participants, even if it's not original msg source
lobby.participating_friends.insert(item->PeerId()) ;
lobby.nick_names.insert(item->nick) ;
// Checks wether the msg is already recorded or not
std::map<ChatLobbyMsgId,time_t>::const_iterator it2(lobby.msg_cache.find(item->msg_id)) ;
if(it2 != lobby.msg_cache.end()) // found!
{
std::cerr << " Msg already received at time " << it2->second << ". Dropping!" << std::endl ;
return false ;
}
std::cerr << " Msg already not received already. Adding in cache, and forwarding!" << std::endl ;
lobby.msg_cache[item->msg_id] = time(NULL) ;
// Forward to allparticipating friends, except this peer.
for(std::set<std::string>::const_iterator it(lobby.participating_friends.begin());it!=lobby.participating_friends.end();++it)
if((*it)!=item->PeerId() && mLinkMgr->isOnline(*it))
{
RsChatLobbyMsgItem *item = new RsChatLobbyMsgItem(*item) ; // copy almost everything
item->PeerId(*it) ;
sendItem(item);
}
return true ;
}
bool p3ChatService::sendLobbyChat(const std::wstring& msg, const ChatLobbyId& lobby_id)
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
std::cerr << "Sending chat lobby message to lobby " << lobby_id << std::endl;
std::cerr << "msg:" << std::endl;
std::cerr << msg.c_str() << std::endl;
// get a pointer to the info for that chat lobby.
//
std::map<ChatLobbyId,ChatLobbyEntry>::const_iterator it(_chat_lobbys.find(lobby_id)) ;
if(it == _chat_lobbys.end())
{
std::cerr << "Chatlobby for id " << std::hex << lobby_id << " has no record. This is a serious error!!" << std::dec << std::endl;
return false ;
}
const ChatLobbyEntry& lobby(it->second) ;
RsChatLobbyMsgItem item ;
// chat lobby stuff
//
do { item.msg_id = RSRandom::random_u64(); } while( lobby.msg_cache.find(item.msg_id) != lobby.msg_cache.end() ) ;
item.lobby_id = lobby_id ;
item.nick = lobby.nick_name ;
// chat msg stuff
//
item.chatFlags = RS_CHAT_FLAG_LOBBY;
item.sendTime = time(NULL);
item.recvTime = item.sendTime;
item.message = msg;
for(std::set<std::string>::const_iterator it(lobby.participating_friends.begin());it!=lobby.participating_friends.end();++it)
if(mLinkMgr->isOnline(*it))
{
RsChatLobbyMsgItem *sitem = new RsChatLobbyMsgItem(item) ; // copies almost everything
sitem->PeerId(*it) ;
sendItem(sitem);
}
return true ;
}
void p3ChatService::getChatLobbyList(std::list<ChatLobbyInfo>& linfos)
{
// fill up a dummy list for now.
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
linfos.clear() ;
ChatLobbyInfo info ;
info.lobby_id = 0x38484fe ;
info.display_name = "lobby 1" ;
info.participating_friends.push_back("friend 1") ;
info.participating_friends.push_back("friend 2") ;
info.additional_peers.push_back("peer 1") ;
linfos.push_back(info) ;
for(std::map<ChatLobbyId,ChatLobbyEntry>::const_iterator it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it)
linfos.push_back(it->second) ;
}
void p3ChatService::invitePeerToLobby(const ChatLobbyId& lobby_id, const std::string& peer_id)
{

View File

@ -156,6 +156,8 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
bool sendLobbyChat(const std::wstring&, const ChatLobbyId&) ;
void getChatLobbyList(std::list<ChatLobbyInfo, std::allocator<ChatLobbyInfo> >&) ;
void invitePeerToLobby(const ChatLobbyId&, const std::string&) ;
void setLobbyNickName(const ChatLobbyNickName&) ;
const ChatLobbyNickName& lobbyNickName() const ;
protected:
@ -203,6 +205,9 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
/// Called when a RsChatMsgItem is received. The item may be collapsed with any waiting partial chat item from the same peer.
bool checkAndRebuildPartialMessage(RsChatMsgItem*) ;
/// receive and handle chat lobby item
bool recvLobbyChat(RsChatLobbyMsgItem*) ;
RsChatAvatarItem *makeOwnAvatarItem() ;
RsChatStatusItem *makeOwnCustomStateStringItem() ;
@ -219,6 +224,17 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
std::string _custom_status_string ;
std::map<std::string,StateStringInfo> _state_strings ;
class ChatLobbyEntry: public ChatLobbyInfo
{
public:
std::map<ChatLobbyMsgId,time_t> msg_cache ;
static const time_t MAX_KEEP_MSG_RECORD = 240 ; // keep msg record for 240 secs max.
void cleanCache() ;
};
std::map<ChatLobbyId,ChatLobbyEntry> _chat_lobbys ;
};
class p3ChatService::StateStringInfo

View File

@ -343,8 +343,8 @@ void FriendList::peerTreeWidgetCostumPopupMenu()
for(std::list<ChatLobbyInfo>::const_iterator it(cl_infos.begin());it!=cl_infos.end();++it)
{
QAction* inviteToLobbyAction = new QAction(QString::fromUtf8((*it).display_name.c_str()), mnu);
inviteToLobbyAction->setData(QString::fromStdString((*it).lobby_id.c_str()));
QAction* inviteToLobbyAction = new QAction(QString::fromUtf8((*it).nick_name.c_str()), mnu);
inviteToLobbyAction->setData(QString::number((*it).lobby_id,16));
connect(inviteToLobbyAction, SIGNAL(triggered()), this, SLOT(inviteToLobby()));
mnu->addAction(inviteToLobbyAction);
}
@ -1411,7 +1411,7 @@ void FriendList::inviteToLobby()
std::string peer_id = getRsId(c) ;
// add to group
rsMsgs->invitePeerToLobby(ChatLobbyId(lobby_id), peer_id);
rsMsgs->invitePeerToLobby(ChatLobbyId(QString::fromStdString(lobby_id).toULongLong()), peer_id);
}
void FriendList::addToGroup()