2007-12-12 01:43:17 +00:00
/*
* " $Id: p3ChatService.cc,v 1.24 2007-05-05 16:10:06 rmf24 Exp $ "
*
* Other Bits for RetroShare .
*
* Copyright 2004 - 2006 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2009-03-29 13:58:28 +00:00
# include "util/rsdir.h"
2011-11-25 21:31:52 +00:00
# include "util/rsrandom.h"
2010-08-06 09:40:23 +00:00
# include "retroshare/rsiface.h"
2011-12-26 14:45:45 +00:00
# include "retroshare/rspeers.h"
2009-03-20 20:41:31 +00:00
# include "pqi/pqibin.h"
2009-03-29 13:58:28 +00:00
# include "pqi/pqinotify.h"
2009-05-09 00:19:54 +00:00
# include "pqi/pqistore.h"
2011-07-09 18:39:34 +00:00
# include "pqi/p3linkmgr.h"
2011-09-29 09:20:09 +00:00
# include "pqi/p3historymgr.h"
2007-12-12 01:43:17 +00:00
# include "services/p3chatservice.h"
2011-12-26 22:43:54 +00:00
# include "serialiser/rsconfigitems.h"
2007-12-12 01:43:17 +00:00
2008-03-02 14:25:59 +00:00
/****
* # define CHAT_DEBUG 1
* * * */
2012-01-14 21:09:04 +00:00
# define CHAT_DEBUG 1
2007-12-12 01:43:17 +00:00
2012-01-07 13:33:30 +00:00
static const int CONNECTION_CHALLENGE_MAX_COUNT = 15 ; // sends a connexion challenge every 15 messages
static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connexion at most every 15 seconds
static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // sends a connexion challenge every 15 messages
static const time_t MAX_KEEP_MSG_RECORD = 240 ; // keep msg record for 240 secs max.
static const time_t MAX_KEEP_INACTIVE_LOBBY = 3600 ; // keep inactive lobbies for 1h max.
2012-01-14 21:09:04 +00:00
static const time_t MAX_KEEP_INACTIVE_NICKNAME = 240 ; // keep inactive lobbies for 1h max.
static const time_t MAX_KEEP_PUBLIC_LOBBY_RECORD = 60 ; // keep inactive lobbies records for 60 secs max.
2012-01-12 21:26:14 +00:00
static const time_t MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ = 20 ; // don't ask for lobby list more than once every 30 secs.
2011-12-26 14:45:45 +00:00
2011-09-29 09:20:09 +00:00
p3ChatService : : p3ChatService ( p3LinkMgr * lm , p3HistoryMgr * historyMgr )
: p3Service ( RS_SERVICE_TYPE_CHAT ) , p3Config ( CONFIG_TYPE_CHAT ) , mChatMtx ( " p3ChatService " ) , mLinkMgr ( lm ) , mHistoryMgr ( historyMgr )
2007-12-12 01:43:17 +00:00
{
addSerialType ( new RsChatSerialiser ( ) ) ;
2009-01-30 19:52:47 +00:00
_own_avatar = NULL ;
2009-09-29 20:37:20 +00:00
_custom_status_string = " " ;
2011-12-26 14:45:45 +00:00
_default_nick_name = rsPeers - > getPeerName ( rsPeers - > getOwnId ( ) ) ;
2012-01-12 20:05:24 +00:00
last_public_lobby_info_request_time = 0 ;
2007-12-12 01:43:17 +00:00
}
int p3ChatService : : tick ( )
{
2010-08-31 17:13:52 +00:00
if ( receivedItems ( ) ) {
receiveChatQueue ( ) ;
}
2011-12-26 22:43:54 +00:00
static time_t last_clean_time = 0 ;
time_t now = time ( NULL ) ;
if ( last_clean_time + LOBBY_CACHE_CLEANING_PERIOD < now )
{
cleanLobbyCaches ( ) ;
last_clean_time = now ;
}
2007-12-12 01:43:17 +00:00
return 0 ;
}
int p3ChatService : : status ( )
{
return 1 ;
}
/***************** Chat Stuff **********************/
2011-09-29 09:20:09 +00:00
int p3ChatService : : sendPublicChat ( const std : : wstring & msg )
2007-12-12 01:43:17 +00:00
{
/* go through all the peers */
2008-01-25 07:49:28 +00:00
std : : list < std : : string > ids ;
std : : list < std : : string > : : iterator it ;
2011-07-09 18:39:34 +00:00
mLinkMgr - > getOnlineList ( ids ) ;
2007-12-12 01:43:17 +00:00
2008-01-25 07:49:28 +00:00
/* add in own id -> so get reflection */
2011-09-29 09:20:09 +00:00
std : : string ownId = mLinkMgr - > getOwnId ( ) ;
ids . push_back ( ownId ) ;
2008-01-25 07:49:28 +00:00
2008-02-04 21:40:34 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3ChatService::sendChat() " ;
std : : cerr < < std : : endl ;
# endif
2008-01-25 07:49:28 +00:00
for ( it = ids . begin ( ) ; it ! = ids . end ( ) ; it + + )
2007-12-12 01:43:17 +00:00
{
2009-05-05 13:18:53 +00:00
RsChatMsgItem * ci = new RsChatMsgItem ( ) ;
2007-12-12 01:43:17 +00:00
2008-01-25 07:49:28 +00:00
ci - > PeerId ( * it ) ;
2007-12-12 01:43:17 +00:00
ci - > chatFlags = 0 ;
ci - > sendTime = time ( NULL ) ;
2010-10-03 10:08:58 +00:00
ci - > recvTime = ci - > sendTime ;
2007-12-12 01:43:17 +00:00
ci - > message = msg ;
2011-09-29 09:20:09 +00:00
2008-02-04 21:40:34 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3ChatService::sendChat() Item: " ;
std : : cerr < < std : : endl ;
ci - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
2011-09-29 09:20:09 +00:00
if ( * it = = ownId ) {
mHistoryMgr - > addMessage ( false , " " , ownId , ci ) ;
}
2007-12-12 01:43:17 +00:00
sendItem ( ci ) ;
}
return 1 ;
}
2009-10-04 22:27:42 +00:00
2009-01-30 19:52:47 +00:00
class p3ChatService : : AvatarInfo
{
public :
2009-02-22 17:36:39 +00:00
AvatarInfo ( )
{
2009-09-29 20:37:20 +00:00
_image_size = 0 ;
_image_data = NULL ;
2009-02-22 17:36:39 +00:00
_peer_is_new = false ; // true when the peer has a new avatar
_own_is_new = false ; // true when I myself a new avatar to send to this peer.
}
2009-09-29 20:37:20 +00:00
~ AvatarInfo ( )
{
delete [ ] _image_data ;
_image_data = NULL ;
_image_size = 0 ;
}
AvatarInfo ( const AvatarInfo & ai )
{
init ( ai . _image_data , ai . _image_size ) ;
}
void init ( const unsigned char * jpeg_data , int size )
{
_image_size = size ;
_image_data = new unsigned char [ size ] ;
memcpy ( _image_data , jpeg_data , size ) ;
}
2009-01-30 19:52:47 +00:00
AvatarInfo ( const unsigned char * jpeg_data , int size )
{
2009-09-29 20:37:20 +00:00
init ( jpeg_data , size ) ;
}
2009-01-30 19:52:47 +00:00
2009-09-29 20:37:20 +00:00
void toUnsignedChar ( unsigned char * & data , uint32_t & size ) const
2009-01-30 19:52:47 +00:00
{
2009-09-29 20:37:20 +00:00
data = new unsigned char [ _image_size ] ;
size = _image_size ;
memcpy ( data , _image_data , size * sizeof ( unsigned char ) ) ;
2009-01-30 19:52:47 +00:00
}
2009-09-29 20:37:20 +00:00
uint32_t _image_size ;
unsigned char * _image_data ;
2009-01-30 19:52:47 +00:00
int _peer_is_new ; // true when the peer has a new avatar
2009-09-29 20:37:20 +00:00
int _own_is_new ; // true when I myself a new avatar to send to this peer.
2009-01-30 19:52:47 +00:00
} ;
2009-09-29 20:37:20 +00:00
void p3ChatService : : sendGroupChatStatusString ( const std : : string & status_string )
{
std : : list < std : : string > ids ;
2011-07-09 18:39:34 +00:00
mLinkMgr - > getOnlineList ( ids ) ;
2009-01-30 19:52:47 +00:00
2009-09-29 20:37:20 +00:00
# ifdef CHAT_DEBUG
2009-10-04 22:27:42 +00:00
std : : cerr < < " p3ChatService::sendChat(): sending group chat status string: " < < status_string < < std : : endl ;
2009-09-29 20:37:20 +00:00
std : : cerr < < std : : endl ;
# endif
for ( std : : list < std : : string > : : iterator it = ids . begin ( ) ; it ! = ids . end ( ) ; + + it )
{
RsChatStatusItem * cs = new RsChatStatusItem ;
cs - > status_string = status_string ;
cs - > flags = RS_CHAT_FLAG_PUBLIC ;
cs - > PeerId ( * it ) ;
sendItem ( cs ) ;
}
}
void p3ChatService : : sendStatusString ( const std : : string & id , const std : : string & status_string )
2009-05-05 13:18:53 +00:00
{
2012-01-06 22:17:08 +00:00
ChatLobbyId lobby_id ;
if ( isLobbyId ( id , lobby_id ) )
sendLobbyStatusString ( lobby_id , status_string ) ;
else
{
RsChatStatusItem * cs = new RsChatStatusItem ;
2009-05-05 13:18:53 +00:00
2012-01-06 22:17:08 +00:00
cs - > status_string = status_string ;
cs - > flags = RS_CHAT_FLAG_PRIVATE ;
cs - > PeerId ( id ) ;
2009-05-05 13:18:53 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " sending chat status packet: " < < std : : endl ;
cs - > print ( std : : cerr ) ;
2009-05-05 13:18:53 +00:00
# endif
2012-01-06 22:17:08 +00:00
sendItem ( cs ) ;
}
2009-05-05 13:18:53 +00:00
}
2012-01-06 22:17:08 +00:00
void p3ChatService : : checkSizeAndSendMessage_deprecated ( RsChatMsgItem * msg )
2011-05-04 20:52:45 +00:00
{
// We check the message item, and possibly split it into multiple messages, if the message is too big.
static const uint32_t MAX_STRING_SIZE = 15000 ;
while ( msg - > message . size ( ) > MAX_STRING_SIZE )
{
// chop off the first 15000 wchars
2012-01-06 22:17:08 +00:00
RsChatMsgItem * item = new RsChatMsgItem ( * msg ) ;
2011-05-04 20:52:45 +00:00
item - > message = item - > message . substr ( 0 , MAX_STRING_SIZE ) ;
msg - > message = msg - > message . substr ( MAX_STRING_SIZE , msg - > message . size ( ) - MAX_STRING_SIZE ) ;
// Clear out any one time flags that should not be copied into multiple objects. This is
// a precaution, in case the receivign peer does not yet handle split messages transparently.
//
2011-12-04 14:31:48 +00:00
item - > chatFlags & = ( RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_PUBLIC | RS_CHAT_FLAG_LOBBY ) ;
2011-05-04 20:52:45 +00:00
// Indicate that the message is to be continued.
//
item - > chatFlags | = RS_CHAT_FLAG_PARTIAL_MESSAGE ;
sendItem ( item ) ;
}
sendItem ( msg ) ;
}
2012-01-06 22:17:08 +00:00
// This function should be used for all types of chat messages. But this requires a non backward compatible change in
// chat protocol. To be done for version 0.6
//
void p3ChatService : : checkSizeAndSendMessage ( RsChatLobbyMsgItem * msg )
{
// We check the message item, and possibly split it into multiple messages, if the message is too big.
static const uint32_t MAX_STRING_SIZE = 15000 ;
int n = 0 ;
while ( msg - > message . size ( ) > MAX_STRING_SIZE )
{
// chop off the first 15000 wchars
RsChatLobbyMsgItem * item = new RsChatLobbyMsgItem ( * msg ) ;
item - > message = item - > message . substr ( 0 , MAX_STRING_SIZE ) ;
msg - > message = msg - > message . substr ( MAX_STRING_SIZE , msg - > message . size ( ) - MAX_STRING_SIZE ) ;
// Clear out any one time flags that should not be copied into multiple objects. This is
// a precaution, in case the receivign peer does not yet handle split messages transparently.
//
item - > chatFlags & = ( RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_PUBLIC | RS_CHAT_FLAG_LOBBY ) ;
// Indicate that the message is to be continued.
//
item - > chatFlags | = RS_CHAT_FLAG_PARTIAL_MESSAGE ;
item - > subpacket_id = n + + ;
sendItem ( item ) ;
}
msg - > subpacket_id = n ;
sendItem ( msg ) ;
}
2011-05-04 20:52:45 +00:00
2011-12-04 22:03:54 +00:00
bool p3ChatService : : getVirtualPeerId ( const ChatLobbyId & id , std : : string & vpid )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 22:22:15 +00:00
std : : cerr < < " Was asked for virtual peer name of " < < std : : hex < < id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-04 22:03:54 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : const_iterator it ( _chat_lobbys . find ( id ) ) ;
if ( it = = _chat_lobbys . end ( ) )
2011-12-04 22:22:15 +00:00
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 22:22:15 +00:00
std : : cerr < < " not found!! " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-04 22:03:54 +00:00
return false ;
2011-12-04 22:22:15 +00:00
}
2011-12-04 22:03:54 +00:00
vpid = it - > second . virtual_peer_id ;
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 22:22:15 +00:00
std : : cerr < < " returning " < < vpid < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-04 22:03:54 +00:00
return true ;
}
2011-12-04 14:31:48 +00:00
void p3ChatService : : locked_printDebugInfo ( ) const
{
std : : cerr < < " Recorded lobbies: " < < std : : endl ;
2012-01-06 22:17:08 +00:00
time_t now = time ( NULL ) ;
2011-12-04 14:31:48 +00:00
for ( std : : map < ChatLobbyId , ChatLobbyEntry > : : const_iterator it ( _chat_lobbys . begin ( ) ) ; it ! = _chat_lobbys . end ( ) ; + + it )
{
2011-12-26 17:39:38 +00:00
std : : cerr < < " Lobby id \t \t : " < < std : : hex < < it - > first < < std : : dec < < std : : endl ;
std : : cerr < < " Lobby name \t \t : " < < it - > second . lobby_name < < std : : endl ;
std : : cerr < < " nick name \t \t : " < < it - > second . nick_name < < std : : endl ;
2012-01-12 20:56:03 +00:00
std : : cerr < < " Lobby type \t \t : " < < ( ( it - > second . lobby_privacy_level = = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ) ? " Public " : " private " ) < < std : : endl ;
2011-12-04 14:31:48 +00:00
std : : cerr < < " Lobby peer id \t : " < < it - > second . virtual_peer_id < < std : : endl ;
2011-12-26 17:39:38 +00:00
std : : cerr < < " Challenge count \t : " < < it - > second . connexion_challenge_count < < std : : endl ;
2012-01-06 22:17:08 +00:00
std : : cerr < < " Last activity \t : " < < now - it - > second . last_activity < < " seconds ago. " < < std : : endl ;
2011-12-26 17:39:38 +00:00
std : : cerr < < " Cached messages \t : " < < it - > second . msg_cache . size ( ) < < std : : endl ;
for ( std : : map < ChatLobbyMsgId , time_t > : : const_iterator it2 ( it - > second . msg_cache . begin ( ) ) ; it2 ! = it - > second . msg_cache . end ( ) ; + + it2 )
2012-01-06 22:17:08 +00:00
std : : cerr < < " " < < std : : hex < < it2 - > first < < std : : dec < < " time= " < < now - it2 - > second < < " secs ago " < < std : : endl ;
2011-12-26 17:39:38 +00:00
2011-12-04 14:31:48 +00:00
std : : cerr < < " Participating friends: " < < std : : endl ;
for ( std : : set < std : : string > : : const_iterator it2 ( it - > second . participating_friends . begin ( ) ) ; it2 ! = it - > second . participating_friends . end ( ) ; + + it2 )
std : : cerr < < " " < < * it2 < < std : : endl ;
std : : cerr < < " Participating nick names: " < < std : : endl ;
2012-01-14 21:09:04 +00:00
for ( std : : map < std : : string , time_t > : : const_iterator it2 ( it - > second . nick_names . begin ( ) ) ; it2 ! = it - > second . nick_names . end ( ) ; + + it2 )
std : : cerr < < " " < < it2 - > first < < " : " < < now - it2 - > second < < " secs ago " < < std : : endl ;
2011-12-04 14:31:48 +00:00
}
std : : cerr < < " Recorded lobby names: " < < std : : endl ;
for ( std : : map < std : : string , ChatLobbyId > : : const_iterator it ( _lobby_ids . begin ( ) ) ; it ! = _lobby_ids . end ( ) ; + + it )
2011-12-26 17:39:38 +00:00
std : : cerr < < " \" " < < it - > first < < " \" id = " < < std : : hex < < it - > second < < std : : dec < < std : : endl ;
2012-01-06 22:17:08 +00:00
std : : cerr < < " Visible public lobbies: " < < std : : endl ;
for ( std : : map < ChatLobbyId , PublicChatLobbyRecord > : : const_iterator it ( _public_lobbies . begin ( ) ) ; it ! = _public_lobbies . end ( ) ; + + it )
{
std : : cerr < < " " < < std : : hex < < it - > first < < " name = " < < std : : dec < < it - > second . lobby_name < < std : : endl ;
for ( std : : set < std : : string > : : const_iterator it2 ( it - > second . participating_friends . begin ( ) ) ; it2 ! = it - > second . participating_friends . end ( ) ; + + it2 )
std : : cerr < < " With friend: " < < * it2 < < std : : endl ;
}
2011-12-04 14:31:48 +00:00
}
bool p3ChatService : : isLobbyId ( const std : : string & id , ChatLobbyId & lobby_id )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , ChatLobbyId > : : const_iterator it ( _lobby_ids . find ( id ) ) ;
if ( it ! = _lobby_ids . end ( ) )
{
lobby_id = it - > second ;
return true ;
}
else
return false ;
}
2011-09-29 09:20:09 +00:00
bool p3ChatService : : sendPrivateChat ( const std : : string & id , const std : : wstring & msg )
2007-12-12 01:43:17 +00:00
{
2011-12-04 14:31:48 +00:00
// look into ID. Is it a peer, or a chat lobby?
ChatLobbyId lobby_id ;
if ( isLobbyId ( id , lobby_id ) )
return sendLobbyChat ( msg , lobby_id ) ;
2007-12-12 01:43:17 +00:00
// make chat item....
2008-02-04 21:40:34 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3ChatService::sendPrivateChat() " ;
std : : cerr < < std : : endl ;
# endif
2007-12-12 01:43:17 +00:00
2009-05-05 13:18:53 +00:00
RsChatMsgItem * ci = new RsChatMsgItem ( ) ;
2007-12-12 01:43:17 +00:00
ci - > PeerId ( id ) ;
ci - > chatFlags = RS_CHAT_FLAG_PRIVATE ;
ci - > sendTime = time ( NULL ) ;
2010-10-03 10:08:58 +00:00
ci - > recvTime = ci - > sendTime ;
2007-12-12 01:43:17 +00:00
ci - > message = msg ;
2011-07-09 18:39:34 +00:00
if ( ! mLinkMgr - > isOnline ( id ) ) {
2010-09-21 00:08:06 +00:00
/* peer is offline, add to outgoing list */
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
privateOutgoingList . push_back ( ci ) ;
}
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PRIVATE_OUTGOING_CHAT , NOTIFY_TYPE_ADD ) ;
IndicateConfigChanged ( ) ;
return false ;
}
2009-01-30 19:52:47 +00:00
{
2009-10-04 22:27:42 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , AvatarInfo * > : : iterator it = _avatars . find ( id ) ;
if ( it = = _avatars . end ( ) )
{
_avatars [ id ] = new AvatarInfo ;
it = _avatars . find ( id ) ;
}
if ( it - > second - > _own_is_new )
{
2009-02-22 17:36:39 +00:00
# ifdef CHAT_DEBUG
2009-10-04 22:27:42 +00:00
std : : cerr < < " p3ChatService::sendPrivateChat: new avatar never sent to peer " < < id < < " . Setting <new> flag to packet. " < < std : : endl ;
2009-02-22 17:36:39 +00:00
# endif
2009-01-30 19:52:47 +00:00
2009-10-04 22:27:42 +00:00
ci - > chatFlags | = RS_CHAT_FLAG_AVATAR_AVAILABLE ;
it - > second - > _own_is_new = false ;
}
2009-01-30 19:52:47 +00:00
}
2008-02-04 21:40:34 +00:00
# ifdef CHAT_DEBUG
2009-02-22 17:36:39 +00:00
std : : cerr < < " Sending msg to peer " < < id < < " , flags = " < < ci - > chatFlags < < std : : endl ;
2008-02-04 21:40:34 +00:00
std : : cerr < < " p3ChatService::sendPrivateChat() Item: " ;
std : : cerr < < std : : endl ;
ci - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
2007-12-12 01:43:17 +00:00
2011-09-29 09:20:09 +00:00
mHistoryMgr - > addMessage ( false , id , mLinkMgr - > getOwnId ( ) , ci ) ;
2012-01-06 22:17:08 +00:00
checkSizeAndSendMessage_deprecated ( ci ) ;
2007-12-12 01:43:17 +00:00
2009-10-04 22:27:42 +00:00
// Check if custom state string has changed, in which case it should be sent to the peer.
bool should_send_state_string = false ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , StateStringInfo > : : iterator it = _state_strings . find ( id ) ;
2010-02-09 20:20:29 +00:00
if ( it = = _state_strings . end ( ) )
2009-10-04 22:27:42 +00:00
{
_state_strings [ id ] = StateStringInfo ( ) ;
it = _state_strings . find ( id ) ;
it - > second . _own_is_new = true ;
}
if ( it - > second . _own_is_new )
{
should_send_state_string = true ;
it - > second . _own_is_new = false ;
}
}
if ( should_send_state_string )
{
# ifdef CHAT_DEBUG
std : : cerr < < " own status string is new for peer " < < id < < " : sending it. " < < std : : endl ;
# endif
RsChatStatusItem * cs = makeOwnCustomStateStringItem ( ) ;
cs - > PeerId ( id ) ;
sendItem ( cs ) ;
}
2010-09-21 00:08:06 +00:00
return true ;
2007-12-12 01:43:17 +00:00
}
2012-01-06 22:17:08 +00:00
bool p3ChatService : : locked_checkAndRebuildPartialMessage_deprecated ( RsChatMsgItem * ci )
2011-05-04 20:52:45 +00:00
{
// Check is the item is ending an incomplete item.
//
std : : map < std : : string , RsChatMsgItem * > : : iterator it = _pendingPartialMessages . find ( ci - > PeerId ( ) ) ;
2012-01-06 22:17:08 +00:00
bool ci_is_incomplete = ci - > chatFlags & RS_CHAT_FLAG_PARTIAL_MESSAGE ;
2011-05-04 20:52:45 +00:00
if ( it ! = _pendingPartialMessages . end ( ) )
{
# ifdef CHAT_DEBUG
2011-12-29 14:19:53 +00:00
std : : cerr < < " Pending message found. Happending it. " < < std : : endl ;
2011-05-04 20:52:45 +00:00
# endif
// Yes, there is. Append the item to ci.
ci - > message = it - > second - > message + ci - > message ;
ci - > chatFlags | = it - > second - > chatFlags ;
delete it - > second ;
2012-01-06 22:17:08 +00:00
if ( ! ci_is_incomplete )
2011-05-04 20:52:45 +00:00
_pendingPartialMessages . erase ( it ) ;
}
2012-01-06 22:17:08 +00:00
if ( ci_is_incomplete )
2011-05-04 20:52:45 +00:00
{
# ifdef CHAT_DEBUG
std : : cerr < < " Message is partial, storing for later. " < < std : : endl ;
# endif
// The item is a partial message. Push it, and wait for the rest.
//
_pendingPartialMessages [ ci - > PeerId ( ) ] = ci ;
return false ;
}
else
{
# ifdef CHAT_DEBUG
std : : cerr < < " Message is complete, using it now. " < < std : : endl ;
# endif
return true ;
}
}
2012-01-06 22:17:08 +00:00
bool p3ChatService : : locked_checkAndRebuildPartialMessage ( RsChatLobbyMsgItem * ci )
2007-12-12 01:43:17 +00:00
{
2012-01-06 22:17:08 +00:00
// Check is the item is ending an incomplete item.
//
std : : map < ChatLobbyMsgId , std : : vector < RsChatLobbyMsgItem * > > : : iterator it = _pendingPartialLobbyMessages . find ( ci - > msg_id ) ;
2007-12-12 01:43:17 +00:00
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Checking chat message for completeness: " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
bool ci_is_incomplete = ci - > chatFlags & RS_CHAT_FLAG_PARTIAL_MESSAGE ;
2010-09-21 00:08:06 +00:00
2012-01-06 22:17:08 +00:00
if ( it ! = _pendingPartialLobbyMessages . end ( ) )
2007-12-12 01:43:17 +00:00
{
2008-04-04 12:19:50 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Pending message found. Happending it. " < < std : : endl ;
2009-02-22 17:36:39 +00:00
# endif
2012-01-06 22:17:08 +00:00
// Yes, there is. Add the item to the list of stored sub-items
2011-12-29 14:19:53 +00:00
2012-01-06 22:17:08 +00:00
if ( ci - > subpacket_id > = it - > second . size ( ) )
it - > second . resize ( ci - > subpacket_id + 1 , NULL ) ;
2011-12-04 14:31:48 +00:00
2012-01-06 22:17:08 +00:00
it - > second [ ci - > subpacket_id ] = ci ;
2009-05-05 13:18:53 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Checking for completeness. " < < std : : endl ;
2009-05-05 13:18:53 +00:00
# endif
2012-01-06 22:17:08 +00:00
// Now check wether we have a complete item or not.
//
bool complete = true ;
for ( uint32_t i = 0 ; i < it - > second . size ( ) & & complete ; + + i )
complete = complete & & ( it - > second [ i ] ! = NULL ) ;
complete = complete & & ! ( it - > second . back ( ) - > chatFlags & RS_CHAT_FLAG_PARTIAL_MESSAGE ) ;
if ( complete )
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Message is complete ! Re-forming it and returning true. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
std : : wstring msg ;
uint32_t flags = 0 ;
2009-05-05 13:18:53 +00:00
2012-01-06 22:17:08 +00:00
for ( uint32_t i = 0 ; i < it - > second . size ( ) ; + + i )
2009-09-29 20:37:20 +00:00
{
2012-01-06 22:17:08 +00:00
msg + = it - > second [ i ] - > message ;
flags | = it - > second [ i ] - > chatFlags ;
if ( i ! = ci - > subpacket_id ) // don't delete ci itself !!
delete it - > second [ i ] ;
2009-09-29 20:37:20 +00:00
}
2012-01-06 22:17:08 +00:00
_pendingPartialLobbyMessages . erase ( it ) ;
ci - > chatFlags = flags ;
ci - > message = msg ;
return true ;
}
else
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Not complete: returning " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
return false ;
}
}
else if ( ci_is_incomplete | | ci - > subpacket_id > 0 ) // the message id might not yet be recorded
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Message is partial, but not recorded. Adding it. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
_pendingPartialLobbyMessages [ ci - > msg_id ] . resize ( ci - > subpacket_id + 1 , NULL ) ;
_pendingPartialLobbyMessages [ ci - > msg_id ] [ ci - > subpacket_id ] = ci ;
return false ;
}
else
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Message is not partial. Returning it as is. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
return true ;
}
}
2009-05-05 13:18:53 +00:00
2012-01-06 22:17:08 +00:00
void p3ChatService : : receiveChatQueue ( )
{
RsItem * item ;
2009-05-05 13:18:53 +00:00
2012-01-06 22:17:08 +00:00
while ( NULL ! = ( item = recvItem ( ) ) )
{
2010-08-31 17:13:52 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " p3ChatService::receiveChatQueue() Item: " < < ( void * ) item < < std : : endl ;
2010-08-31 17:13:52 +00:00
# endif
2012-01-06 22:17:08 +00:00
// RsChatMsgItems needs dynamic_cast, since they have derived siblings.
//
RsChatMsgItem * ci = dynamic_cast < RsChatMsgItem * > ( item ) ;
if ( ci ! = NULL )
{
if ( ! handleRecvChatMsgItem ( ci ) )
delete ci ;
2009-05-05 13:18:53 +00:00
2012-01-06 22:17:08 +00:00
continue ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
}
2010-08-31 17:13:52 +00:00
2012-01-06 22:17:08 +00:00
switch ( item - > PacketSubType ( ) )
{
case RS_PKT_SUBTYPE_CHAT_STATUS : handleRecvChatStatusItem ( dynamic_cast < RsChatStatusItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_AVATAR : handleRecvChatAvatarItem ( dynamic_cast < RsChatAvatarItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE : handleRecvLobbyInvite ( dynamic_cast < RsChatLobbyInviteItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE : handleConnectionChallenge ( dynamic_cast < RsChatLobbyConnectChallengeItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT : handleRecvChatLobbyEventItem ( dynamic_cast < RsChatLobbyEventItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE : handleFriendUnsubscribeLobby ( dynamic_cast < RsChatLobbyUnsubscribeItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST : handleRecvChatLobbyListRequest ( dynamic_cast < RsChatLobbyListRequestItem * > ( item ) ) ; break ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST : handleRecvChatLobbyList ( dynamic_cast < RsChatLobbyListItem * > ( item ) ) ; break ;
default :
std : : cerr < < " Unhandled item subtype " < < item - > PacketSubType ( ) < < " in p3ChatService: " < < std : : endl ;
}
delete item ;
}
}
2010-08-31 17:13:52 +00:00
2012-01-07 13:33:30 +00:00
void p3ChatService : : handleRecvChatLobbyListRequest ( RsChatLobbyListRequestItem * clr )
2012-01-06 22:17:08 +00:00
{
2012-01-07 13:33:30 +00:00
// make a lobby list item
//
RsChatLobbyListItem * item = new RsChatLobbyListItem ;
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-07 13:33:30 +00:00
std : : cerr < < " Peer " < < clr - > PeerId ( ) < < " requested the list of public chat lobbies. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-07 13:33:30 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
for ( std : : map < ChatLobbyId , ChatLobbyEntry > : : const_iterator it ( _chat_lobbys . begin ( ) ) ; it ! = _chat_lobbys . end ( ) ; + + it )
if ( it - > second . lobby_privacy_level = = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC )
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-07 13:33:30 +00:00
std : : cerr < < " Adding lobby " < < std : : hex < < it - > first < < std : : dec < < " \" " < < it - > second . lobby_name < < " \" count= " < < it - > second . nick_names . size ( ) < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-07 13:33:30 +00:00
item - > lobby_ids . push_back ( it - > first ) ;
item - > lobby_names . push_back ( it - > second . lobby_name ) ;
item - > lobby_counts . push_back ( it - > second . nick_names . size ( ) ) ;
}
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-07 13:33:30 +00:00
else
std : : cerr < < " Not adding private lobby " < < std : : hex < < it - > first < < std : : dec < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-07 13:33:30 +00:00
}
item - > PeerId ( clr - > PeerId ( ) ) ;
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-07 13:33:30 +00:00
std : : cerr < < " Sending list to " < < clr - > PeerId ( ) < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-07 13:33:30 +00:00
sendItem ( item ) ;
2012-01-06 22:17:08 +00:00
}
2012-01-07 13:33:30 +00:00
2012-01-06 22:17:08 +00:00
void p3ChatService : : handleRecvChatLobbyList ( RsChatLobbyListItem * item )
{
2012-01-07 13:33:30 +00:00
{
2012-01-14 21:09:04 +00:00
time_t now = time ( NULL ) ;
2012-01-07 13:33:30 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
for ( uint32_t i = 0 ; i < item - > lobby_ids . size ( ) ; + + i )
{
PublicChatLobbyRecord & rec ( _public_lobbies [ item - > lobby_ids [ i ] ] ) ;
rec . lobby_id = item - > lobby_ids [ i ] ;
rec . lobby_name = item - > lobby_names [ i ] ;
rec . participating_friends . insert ( item - > PeerId ( ) ) ;
rec . total_number_of_peers = item - > lobby_counts [ i ] ;
2012-01-14 21:09:04 +00:00
rec . last_report_time = now ;
2012-01-07 13:33:30 +00:00
}
}
2012-01-12 00:13:25 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_ADD ) ;
2012-01-06 22:17:08 +00:00
}
2010-08-31 17:13:52 +00:00
2012-01-06 22:17:08 +00:00
void p3ChatService : : handleRecvChatLobbyEventItem ( RsChatLobbyEventItem * item )
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " Received ChatLobbyEvent item of type " < < ( int ) ( item - > event_type ) < < " , and string= " < < item - > string1 < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2011-09-29 09:20:09 +00:00
2012-01-06 22:17:08 +00:00
if ( ! bounceLobbyObject ( item , item - > PeerId ( ) ) )
return ;
2009-09-29 20:37:20 +00:00
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " doing specific job for this status item. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
if ( item - > event_type = = RS_CHAT_LOBBY_EVENT_PEER_LEFT ) // if a peer left. Remove its nickname from the list.
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " removing nickname " < < item - > nick < < " from lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( item - > lobby_id ) ;
if ( it ! = _chat_lobbys . end ( ) )
{
2012-01-14 21:09:04 +00:00
std : : map < std : : string , time_t > : : iterator it2 ( it - > second . nick_names . find ( item - > nick ) ) ;
2012-01-12 21:23:16 +00:00
if ( it2 ! = it - > second . nick_names . end ( ) )
{
it - > second . nick_names . erase ( it2 ) ;
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " removed nickname " < < item - > nick < < " from lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
}
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
else
std : : cerr < < " (EE) nickname " < < item - > nick < < " not in participant nicknames list! " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
}
}
if ( item - > event_type = = RS_CHAT_LOBBY_EVENT_PEER_JOINED ) // if a joined left. Add its nickname to the list.
{
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " adding nickname " < < item - > nick < < " to lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( item - > lobby_id ) ;
if ( it ! = _chat_lobbys . end ( ) )
{
2012-01-14 21:09:04 +00:00
it - > second . nick_names [ item - > nick ] = time ( NULL ) ;
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-12 21:23:16 +00:00
std : : cerr < < " added nickname " < < item - > nick < < " from lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-12 21:23:16 +00:00
}
}
2012-01-06 22:17:08 +00:00
rsicontrol - > getNotify ( ) . notifyChatLobbyEvent ( item - > lobby_id , item - > event_type , item - > nick , item - > string1 ) ;
}
void p3ChatService : : handleRecvChatAvatarItem ( RsChatAvatarItem * ca )
{
receiveAvatarJpegData ( ca ) ;
2009-05-05 13:18:53 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Received avatar data for peer " < < ca - > PeerId ( ) < < " . Notifying. " < < std : : endl ;
2009-05-05 13:18:53 +00:00
# endif
2012-01-06 22:17:08 +00:00
rsicontrol - > getNotify ( ) . notifyPeerHasNewAvatar ( ca - > PeerId ( ) ) ;
}
2009-09-29 20:37:20 +00:00
2012-01-06 22:17:08 +00:00
bool p3ChatService : : handleRecvChatMsgItem ( RsChatMsgItem * ci )
{
bool publicChanged = false ;
bool privateChanged = false ;
2009-09-29 20:37:20 +00:00
2012-01-06 22:17:08 +00:00
time_t now = time ( NULL ) ;
2009-09-29 20:37:20 +00:00
2012-01-06 22:17:08 +00:00
// check if it's a lobby msg, in which case we replace the peer id by the lobby's virtual peer id.
//
RsChatLobbyMsgItem * cli = dynamic_cast < RsChatLobbyMsgItem * > ( ci ) ;
2009-09-29 20:37:20 +00:00
2012-01-06 22:17:08 +00:00
if ( cli ! = NULL )
{
2009-09-29 20:37:20 +00:00
{
2012-01-06 22:17:08 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-09-30 20:53:18 +00:00
2012-01-06 22:17:08 +00:00
if ( ! locked_checkAndRebuildPartialMessage ( cli ) )
return true ;
2009-01-30 19:52:47 +00:00
}
2011-11-28 22:36:13 +00:00
2012-01-06 22:17:08 +00:00
if ( ! bounceLobbyObject ( cli , cli - > PeerId ( ) ) ) // forwards the message to friends, keeps track of subscribers, etc.
return false ;
// setup the peer id to the virtual peer id of the lobby.
//
std : : string virtual_peer_id ;
getVirtualPeerId ( cli - > lobby_id , virtual_peer_id ) ;
cli - > PeerId ( virtual_peer_id ) ;
}
else
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
if ( ! locked_checkAndRebuildPartialMessage_deprecated ( ci ) ) // Don't delete ! This function is not handled propoerly for chat lobby msgs, so
return true ; // we don't use it in this case.
}
# ifdef CHAT_DEBUG
std : : cerr < < " p3ChatService::receiveChatQueue() Item: " ;
std : : cerr < < std : : endl ;
ci - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
std : : cerr < < " Got msg. Flags = " < < ci - > chatFlags < < std : : endl ;
# endif
2011-11-28 22:36:13 +00:00
2012-01-06 22:17:08 +00:00
if ( ci - > chatFlags & RS_CHAT_FLAG_REQUESTS_AVATAR ) // no msg here. Just an avatar request.
{
sendAvatarJpegData ( ci - > PeerId ( ) ) ;
return false ;
}
else // normal msg. Return it normally.
{
// Check if new avatar is available at peer's. If so, send a request to get the avatar.
if ( ci - > chatFlags & RS_CHAT_FLAG_AVATAR_AVAILABLE )
2011-11-28 22:36:13 +00:00
{
2012-01-06 22:17:08 +00:00
std : : cerr < < " New avatar is available for peer " < < ci - > PeerId ( ) < < " , sending request " < < std : : endl ;
sendAvatarRequest ( ci - > PeerId ( ) ) ;
ci - > chatFlags & = ~ RS_CHAT_FLAG_AVATAR_AVAILABLE ;
2011-11-28 22:36:13 +00:00
}
2012-01-06 22:17:08 +00:00
std : : map < std : : string , AvatarInfo * > : : const_iterator it = _avatars . find ( ci - > PeerId ( ) ) ;
2011-12-26 14:45:45 +00:00
2012-01-06 22:17:08 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3chatservice:: avatar requested from above. " < < std : : endl ;
# endif
// has avatar. Return it strait away.
//
if ( it ! = _avatars . end ( ) & & it - > second - > _peer_is_new )
2011-12-26 14:45:45 +00:00
{
2012-01-06 22:17:08 +00:00
std : : cerr < < " Avatar is new for peer. ending info above " < < std : : endl ;
ci - > chatFlags | = RS_CHAT_FLAG_AVATAR_AVAILABLE ;
2011-12-26 14:45:45 +00:00
}
2012-01-06 22:17:08 +00:00
if ( ( ci - > chatFlags & RS_CHAT_FLAG_PRIVATE ) = = 0 ) {
/* notify public chat message */
std : : string message ;
message . assign ( ci - > message . begin ( ) , ci - > message . end ( ) ) ;
getPqiNotify ( ) - > AddFeedItem ( RS_FEED_ITEM_CHAT_NEW , ci - > PeerId ( ) , message , " " ) ;
}
2011-12-27 13:47:37 +00:00
{
2012-01-06 22:17:08 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
ci - > recvTime = now ;
2011-12-27 13:47:37 +00:00
2012-01-06 22:17:08 +00:00
if ( ci - > chatFlags & RS_CHAT_FLAG_PRIVATE ) {
std : : cerr < < " Adding msg 0x " < < std : : hex < < ( void * ) ci < < std : : dec < < " to private chat incoming list. " < < std : : endl ;
privateChanged = true ;
privateIncomingList . push_back ( ci ) ; // don't delete the item !!
} else {
std : : cerr < < " Adding msg 0x " < < std : : hex < < ( void * ) ci < < std : : dec < < " to public chat incoming list. " < < std : : endl ;
publicChanged = true ;
publicList . push_back ( ci ) ; // don't delete the item !!
2011-12-26 14:45:45 +00:00
2012-01-06 22:17:08 +00:00
if ( ci - > PeerId ( ) ! = mLinkMgr - > getOwnId ( ) ) {
/* not from loop back */
mHistoryMgr - > addMessage ( true , " " , ci - > PeerId ( ) , ci ) ;
}
}
} /* UNLOCK */
2007-12-12 01:43:17 +00:00
}
2010-09-01 17:56:15 +00:00
if ( publicChanged ) {
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PUBLIC_CHAT , NOTIFY_TYPE_ADD ) ;
}
if ( privateChanged ) {
2010-09-21 00:08:06 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PRIVATE_INCOMING_CHAT , NOTIFY_TYPE_ADD ) ;
IndicateConfigChanged ( ) ; // only private chat messages are saved
2010-09-01 17:56:15 +00:00
}
2012-01-06 22:17:08 +00:00
return true ;
}
void p3ChatService : : handleRecvChatStatusItem ( RsChatStatusItem * cs )
{
# ifdef CHAT_DEBUG
std : : cerr < < " Received status string \" " < < cs - > status_string < < " \" " < < std : : endl ;
# endif
if ( cs - > flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE ) // no state here just a request.
sendCustomState ( cs - > PeerId ( ) ) ;
else if ( cs - > flags & RS_CHAT_FLAG_CUSTOM_STATE ) // Check if new custom string is available at peer's.
{ // If so, send a request to get the custom string.
receiveStateString ( cs - > PeerId ( ) , cs - > status_string ) ; // store it
rsicontrol - > getNotify ( ) . notifyCustomState ( cs - > PeerId ( ) , cs - > status_string ) ;
}
else if ( cs - > flags & RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE )
{
std : : cerr < < " New custom state is available for peer " < < cs - > PeerId ( ) < < " , sending request " < < std : : endl ;
sendCustomStateRequest ( cs - > PeerId ( ) ) ;
}
else if ( cs - > flags & RS_CHAT_FLAG_PRIVATE )
rsicontrol - > getNotify ( ) . notifyChatStatus ( cs - > PeerId ( ) , cs - > status_string , true ) ;
else if ( cs - > flags & RS_CHAT_FLAG_PUBLIC )
rsicontrol - > getNotify ( ) . notifyChatStatus ( cs - > PeerId ( ) , cs - > status_string , false ) ;
}
void p3ChatService : : getListOfNearbyChatLobbies ( std : : vector < PublicChatLobbyRecord > & public_lobbies )
{
2012-01-07 13:33:30 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2012-01-06 22:17:08 +00:00
2012-01-07 13:33:30 +00:00
public_lobbies . clear ( ) ;
for ( std : : map < ChatLobbyId , PublicChatLobbyRecord > : : const_iterator it ( _public_lobbies . begin ( ) ) ; it ! = _public_lobbies . end ( ) ; + + it )
public_lobbies . push_back ( it - > second ) ;
}
2012-01-06 22:17:08 +00:00
2012-01-07 13:33:30 +00:00
time_t now = time ( NULL ) ;
if ( now > MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ + last_public_lobby_info_request_time )
{
std : : list < std : : string > ids ;
mLinkMgr - > getOnlineList ( ids ) ;
for ( std : : list < std : : string > : : const_iterator it ( ids . begin ( ) ) ; it ! = ids . end ( ) ; + + it )
{
std : : cerr < < " asking list of public lobbies to " < < * it < < std : : endl ;
RsChatLobbyListRequestItem * item = new RsChatLobbyListRequestItem ;
item - > PeerId ( * it ) ;
sendItem ( item ) ;
}
last_public_lobby_info_request_time = now ;
}
2010-09-01 17:56:15 +00:00
}
2010-09-21 00:08:06 +00:00
int p3ChatService : : getPublicChatQueueCount ( )
2010-09-01 17:56:15 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
return publicList . size ( ) ;
}
bool p3ChatService : : getPublicChatQueue ( std : : list < ChatInfo > & chats )
{
bool changed = false ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
// get the items from the public list.
if ( publicList . size ( ) = = 0 ) {
return false ;
}
std : : list < RsChatMsgItem * > : : iterator it ;
while ( publicList . size ( ) ) {
RsChatMsgItem * c = publicList . front ( ) ;
publicList . pop_front ( ) ;
ChatInfo ci ;
initRsChatInfo ( c , ci ) ;
chats . push_back ( ci ) ;
changed = true ;
delete c ;
}
} /* UNLOCKED */
2010-08-31 17:13:52 +00:00
if ( changed ) {
2010-09-01 17:56:15 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PUBLIC_CHAT , NOTIFY_TYPE_DEL ) ;
2010-08-31 17:13:52 +00:00
}
2010-09-01 17:56:15 +00:00
return true ;
2010-08-31 17:13:52 +00:00
}
2010-09-21 00:08:06 +00:00
int p3ChatService : : getPrivateChatQueueCount ( bool incoming )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
if ( incoming ) {
return privateIncomingList . size ( ) ;
}
return privateOutgoingList . size ( ) ;
}
bool p3ChatService : : getPrivateChatQueueIds ( bool incoming , std : : list < std : : string > & ids )
2010-08-31 17:13:52 +00:00
{
2010-09-01 17:56:15 +00:00
ids . clear ( ) ;
2010-08-31 17:13:52 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2010-09-21 00:08:06 +00:00
std : : list < RsChatMsgItem * > * list ;
if ( incoming ) {
list = & privateIncomingList ;
} else {
list = & privateOutgoingList ;
}
2010-09-01 17:56:15 +00:00
// get the items from the private list.
2010-09-21 00:08:06 +00:00
if ( list - > size ( ) = = 0 ) {
2010-08-31 17:13:52 +00:00
return false ;
}
std : : list < RsChatMsgItem * > : : iterator it ;
2010-09-21 00:08:06 +00:00
for ( it = list - > begin ( ) ; it ! = list - > end ( ) ; it + + ) {
2010-09-01 17:56:15 +00:00
RsChatMsgItem * c = * it ;
if ( std : : find ( ids . begin ( ) , ids . end ( ) , c - > PeerId ( ) ) = = ids . end ( ) ) {
ids . push_back ( c - > PeerId ( ) ) ;
}
}
return true ;
}
2010-09-21 00:08:06 +00:00
bool p3ChatService : : getPrivateChatQueue ( bool incoming , const std : : string & id , std : : list < ChatInfo > & chats )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : list < RsChatMsgItem * > * list ;
if ( incoming ) {
list = & privateIncomingList ;
} else {
list = & privateOutgoingList ;
}
// get the items from the private list.
if ( list - > size ( ) = = 0 ) {
return false ;
}
std : : list < RsChatMsgItem * > : : iterator it ;
for ( it = list - > begin ( ) ; it ! = list - > end ( ) ; it + + ) {
RsChatMsgItem * c = * it ;
if ( c - > PeerId ( ) = = id ) {
ChatInfo ci ;
initRsChatInfo ( c , ci ) ;
chats . push_back ( ci ) ;
}
}
return ( chats . size ( ) > 0 ) ;
}
bool p3ChatService : : clearPrivateChatQueue ( bool incoming , const std : : string & id )
2010-09-01 17:56:15 +00:00
{
bool changed = false ;
2010-08-31 17:13:52 +00:00
{
2010-09-01 17:56:15 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2010-09-21 00:08:06 +00:00
std : : list < RsChatMsgItem * > * list ;
if ( incoming ) {
list = & privateIncomingList ;
} else {
list = & privateOutgoingList ;
}
2010-09-01 17:56:15 +00:00
// get the items from the private list.
2010-09-21 00:08:06 +00:00
if ( list - > size ( ) = = 0 ) {
2010-09-01 17:56:15 +00:00
return false ;
}
2010-09-21 00:08:06 +00:00
std : : list < RsChatMsgItem * > : : iterator it = list - > begin ( ) ;
while ( it ! = list - > end ( ) ) {
2010-09-01 17:56:15 +00:00
RsChatMsgItem * c = * it ;
if ( c - > PeerId ( ) = = id ) {
2011-10-01 20:50:39 +00:00
if ( incoming ) {
mHistoryMgr - > addMessage ( true , c - > PeerId ( ) , c - > PeerId ( ) , c ) ;
}
2010-09-01 17:56:15 +00:00
delete c ;
2010-09-21 00:08:06 +00:00
changed = true ;
2010-08-31 17:13:52 +00:00
2010-09-01 17:56:15 +00:00
std : : list < RsChatMsgItem * > : : iterator it1 = it ;
it + + ;
2010-09-21 00:08:06 +00:00
list - > erase ( it1 ) ;
2010-09-01 17:56:15 +00:00
continue ;
}
it + + ;
}
} /* UNLOCKED */
if ( changed ) {
2010-09-21 00:08:06 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( incoming ? NOTIFY_LIST_PRIVATE_INCOMING_CHAT : NOTIFY_LIST_PRIVATE_OUTGOING_CHAT , NOTIFY_TYPE_DEL ) ;
IndicateConfigChanged ( ) ;
2010-08-31 17:13:52 +00:00
}
2010-09-01 17:56:15 +00:00
2010-08-31 17:13:52 +00:00
return true ;
}
void p3ChatService : : initRsChatInfo ( RsChatMsgItem * c , ChatInfo & i )
{
2010-09-04 14:23:30 +00:00
i . rsid = c - > PeerId ( ) ;
i . chatflags = 0 ;
2010-10-03 10:08:58 +00:00
i . sendTime = c - > sendTime ;
i . recvTime = c - > recvTime ;
2010-09-04 14:23:30 +00:00
i . msg = c - > message ;
2010-08-31 17:13:52 +00:00
2011-12-04 14:31:48 +00:00
RsChatLobbyMsgItem * lobbyItem = dynamic_cast < RsChatLobbyMsgItem * > ( c ) ;
if ( lobbyItem ! = NULL )
i . peer_nickname = lobbyItem - > nick ;
2010-08-31 17:13:52 +00:00
if ( c - > chatFlags & RS_CHAT_FLAG_PRIVATE )
i . chatflags | = RS_CHAT_PRIVATE ;
else
i . chatflags | = RS_CHAT_PUBLIC ;
2007-12-12 01:43:17 +00:00
}
2009-10-04 22:27:42 +00:00
void p3ChatService : : setOwnCustomStateString ( const std : : string & s )
2009-09-29 20:37:20 +00:00
{
2010-04-24 10:33:12 +00:00
std : : list < std : : string > onlineList ;
2009-09-29 20:37:20 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3chatservice: Setting own state string to new value : " < < s < < std : : endl ;
# endif
2009-09-29 20:37:20 +00:00
_custom_status_string = s ;
2009-10-04 22:27:42 +00:00
for ( std : : map < std : : string , StateStringInfo > : : iterator it ( _state_strings . begin ( ) ) ; it ! = _state_strings . end ( ) ; + + it )
it - > second . _own_is_new = true ;
2010-04-24 10:33:12 +00:00
2011-07-09 18:39:34 +00:00
mLinkMgr - > getOnlineList ( onlineList ) ;
2009-09-29 20:37:20 +00:00
}
2009-10-05 19:55:17 +00:00
rsicontrol - > getNotify ( ) . notifyOwnStatusMessageChanged ( ) ;
2010-04-24 10:33:12 +00:00
// alert your online peers to your newly set status
std : : list < std : : string > : : iterator it ( onlineList . begin ( ) ) ;
for ( ; it ! = onlineList . end ( ) ; it + + ) {
RsChatStatusItem * cs = new RsChatStatusItem ( ) ;
cs - > flags = RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE ;
cs - > status_string = " " ;
cs - > PeerId ( * it ) ;
sendItem ( cs ) ;
}
2009-09-29 20:37:20 +00:00
IndicateConfigChanged ( ) ;
}
2009-01-30 19:52:47 +00:00
void p3ChatService : : setOwnAvatarJpegData ( const unsigned char * data , int size )
{
2009-03-20 20:41:31 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-03-20 20:41:31 +00:00
std : : cerr < < " p3chatservice: Setting own avatar to new image. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
2009-03-20 20:41:31 +00:00
if ( _own_avatar ! = NULL )
delete _own_avatar ;
2009-01-30 19:52:47 +00:00
2009-03-20 20:41:31 +00:00
_own_avatar = new AvatarInfo ( data , size ) ;
// set the info that our avatar is new, for all peers
for ( std : : map < std : : string , AvatarInfo * > : : iterator it ( _avatars . begin ( ) ) ; it ! = _avatars . end ( ) ; + + it )
it - > second - > _own_is_new = true ;
}
IndicateConfigChanged ( ) ;
2009-10-04 22:27:42 +00:00
rsicontrol - > getNotify ( ) . notifyOwnAvatarChanged ( ) ;
# ifdef CHAT_DEBUG
2009-05-08 23:07:08 +00:00
std : : cerr < < " p3chatservice:setOwnAvatarJpegData() done. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
}
2009-10-04 22:27:42 +00:00
void p3ChatService : : receiveStateString ( const std : : string & id , const std : : string & s )
2009-01-30 19:52:47 +00:00
{
2009-03-20 20:41:31 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2010-04-24 10:33:12 +00:00
std : : cerr < < " p3chatservice: received custom state string for peer " < < id < < " . Storing it. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
2009-10-04 22:27:42 +00:00
bool new_peer = ( _state_strings . find ( id ) = = _state_strings . end ( ) ) ;
2009-01-30 19:52:47 +00:00
2009-10-04 22:27:42 +00:00
_state_strings [ id ] . _custom_status_string = s ;
_state_strings [ id ] . _peer_is_new = true ;
_state_strings [ id ] . _own_is_new = new_peer ;
2009-01-30 19:52:47 +00:00
}
2010-09-13 20:28:21 +00:00
2009-09-29 20:37:20 +00:00
void p3ChatService : : receiveAvatarJpegData ( RsChatAvatarItem * ci )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-09-29 20:37:20 +00:00
std : : cerr < < " p3chatservice: received avatar jpeg data for peer " < < ci - > PeerId ( ) < < " . Storing it. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-09-29 20:37:20 +00:00
bool new_peer = ( _avatars . find ( ci - > PeerId ( ) ) = = _avatars . end ( ) ) ;
2010-09-13 20:28:21 +00:00
if ( new_peer = = false & & _avatars [ ci - > PeerId ( ) ] ) {
delete _avatars [ ci - > PeerId ( ) ] ;
}
2009-09-29 20:37:20 +00:00
_avatars [ ci - > PeerId ( ) ] = new AvatarInfo ( ci - > image_data , ci - > image_size ) ;
_avatars [ ci - > PeerId ( ) ] - > _peer_is_new = true ;
_avatars [ ci - > PeerId ( ) ] - > _own_is_new = new_peer ;
}
2009-01-30 19:52:47 +00:00
2009-10-04 22:27:42 +00:00
std : : string p3ChatService : : getOwnCustomStateString ( )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
return _custom_status_string ;
}
2009-01-30 19:52:47 +00:00
void p3ChatService : : getOwnAvatarJpegData ( unsigned char * & data , int & size )
{
// should be a Mutex here.
2009-03-20 20:41:31 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-01-30 19:52:47 +00:00
2009-09-29 20:37:20 +00:00
uint32_t s = 0 ;
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-01-30 19:52:47 +00:00
std : : cerr < < " p3chatservice:: own avatar requested from above. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
// has avatar. Return it strait away.
//
if ( _own_avatar ! = NULL )
2009-09-29 20:37:20 +00:00
{
_own_avatar - > toUnsignedChar ( data , s ) ;
size = s ;
}
2009-01-30 19:52:47 +00:00
else
{
data = NULL ;
size = 0 ;
}
}
2009-10-04 22:27:42 +00:00
std : : string p3ChatService : : getCustomStateString ( const std : : string & peer_id )
{
// should be a Mutex here.
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , StateStringInfo > : : iterator it = _state_strings . find ( peer_id ) ;
# ifdef CHAT_DEBUG
std : : cerr < < " p3chatservice:: status string for peer " < < peer_id < < " requested from above. " < < std : : endl ;
# endif
// has it. Return it strait away.
//
if ( it ! = _state_strings . end ( ) )
{
it - > second . _peer_is_new = false ;
# ifdef CHAT_DEBUG
std : : cerr < < " Already has status string. Returning it " < < std : : endl ;
# endif
return it - > second . _custom_status_string ;
}
2010-04-24 10:33:12 +00:00
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2010-04-24 10:33:12 +00:00
std : : cerr < < " No status string for this peer. requesting it. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2010-04-24 10:33:12 +00:00
sendCustomStateRequest ( peer_id ) ;
return std : : string ( ) ;
2009-10-04 22:27:42 +00:00
}
2009-01-30 19:52:47 +00:00
void p3ChatService : : getAvatarJpegData ( const std : : string & peer_id , unsigned char * & data , int & size )
{
// should be a Mutex here.
2009-03-20 20:41:31 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-01-30 19:52:47 +00:00
std : : map < std : : string , AvatarInfo * > : : const_iterator it = _avatars . find ( peer_id ) ;
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-09-30 20:53:18 +00:00
std : : cerr < < " p3chatservice:: avatar for peer " < < peer_id < < " requested from above. " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2010-04-24 10:33:12 +00:00
// has avatar. Return it straight away.
2009-01-30 19:52:47 +00:00
//
if ( it ! = _avatars . end ( ) )
{
2009-09-29 20:37:20 +00:00
uint32_t s = 0 ;
it - > second - > toUnsignedChar ( data , s ) ;
size = s ;
2009-01-30 19:52:47 +00:00
it - > second - > _peer_is_new = false ;
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-01-30 19:52:47 +00:00
std : : cerr < < " Already has avatar. Returning it " < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
return ;
2010-02-10 10:56:54 +00:00
} else {
# ifdef CHAT_DEBUG
2009-01-30 19:52:47 +00:00
std : : cerr < < " No avatar for this peer. Requesting it by sending request packet. " < < std : : endl ;
2010-02-10 10:56:54 +00:00
# endif
}
2009-01-30 19:52:47 +00:00
2010-02-10 10:56:54 +00:00
sendAvatarRequest ( peer_id ) ;
2009-01-30 19:52:47 +00:00
}
void p3ChatService : : sendAvatarRequest ( const std : : string & peer_id )
{
// Doesn't have avatar. Request it.
//
2009-05-05 13:18:53 +00:00
RsChatMsgItem * ci = new RsChatMsgItem ( ) ;
2009-01-30 19:52:47 +00:00
ci - > PeerId ( peer_id ) ;
ci - > chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_REQUESTS_AVATAR ;
ci - > sendTime = time ( NULL ) ;
2010-08-06 21:14:25 +00:00
ci - > message . erase ( ) ;
2009-01-30 19:52:47 +00:00
2009-10-04 22:27:42 +00:00
# ifdef CHAT_DEBUG
2009-01-30 19:52:47 +00:00
std : : cerr < < " p3ChatService::sending request for avatar, to peer " < < peer_id < < std : : endl ;
std : : cerr < < std : : endl ;
2009-10-04 22:27:42 +00:00
# endif
2009-01-30 19:52:47 +00:00
sendItem ( ci ) ;
}
2010-04-24 10:33:12 +00:00
void p3ChatService : : sendCustomStateRequest ( const std : : string & peer_id ) {
RsChatStatusItem * cs = new RsChatStatusItem ;
cs - > PeerId ( peer_id ) ;
cs - > flags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_REQUEST_CUSTOM_STATE ;
2010-08-06 21:14:25 +00:00
cs - > status_string . erase ( ) ;
2010-04-24 10:33:12 +00:00
# ifdef CHAT_DEBUG
std : : cerr < < " p3ChatService::sending request for status, to peer " < < peer_id < < std : : endl ;
std : : cerr < < std : : endl ;
# endif
sendItem ( cs ) ;
}
2009-10-04 22:27:42 +00:00
RsChatStatusItem * p3ChatService : : makeOwnCustomStateStringItem ( )
2009-03-20 20:41:31 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-10-04 22:27:42 +00:00
RsChatStatusItem * ci = new RsChatStatusItem ( ) ;
2009-03-20 20:41:31 +00:00
2009-10-04 22:27:42 +00:00
ci - > flags = RS_CHAT_FLAG_CUSTOM_STATE ;
ci - > status_string = _custom_status_string ;
return ci ;
}
RsChatAvatarItem * p3ChatService : : makeOwnAvatarItem ( )
{
2009-09-29 20:37:20 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
RsChatAvatarItem * ci = new RsChatAvatarItem ( ) ;
_own_avatar - > toUnsignedChar ( ci - > image_data , ci - > image_size ) ;
2009-03-20 20:41:31 +00:00
return ci ;
}
2009-01-30 19:52:47 +00:00
void p3ChatService : : sendAvatarJpegData ( const std : : string & peer_id )
{
2010-02-10 10:56:54 +00:00
# ifdef CHAT_DEBUG
2009-01-30 19:52:47 +00:00
std : : cerr < < " p3chatservice: sending requested for peer " < < peer_id < < " , data= " < < ( void * ) _own_avatar < < std : : endl ;
2010-02-10 10:56:54 +00:00
# endif
2009-01-30 19:52:47 +00:00
if ( _own_avatar ! = NULL )
2009-03-20 20:41:31 +00:00
{
2009-09-29 20:37:20 +00:00
RsChatAvatarItem * ci = makeOwnAvatarItem ( ) ;
2009-03-20 20:41:31 +00:00
ci - > PeerId ( peer_id ) ;
2009-01-30 19:52:47 +00:00
2009-03-20 20:41:31 +00:00
// take avatar, and embed it into a std::wstring.
//
2010-03-28 20:46:45 +00:00
# ifdef CHAT_DEBUG
2009-09-29 20:37:20 +00:00
std : : cerr < < " p3ChatService::sending avatar image to peer " < < peer_id < < " , image size = " < < ci - > image_size < < std : : endl ;
2009-03-20 20:41:31 +00:00
std : : cerr < < std : : endl ;
2010-03-28 20:46:45 +00:00
# endif
2009-01-30 19:52:47 +00:00
2009-03-20 20:41:31 +00:00
sendItem ( ci ) ;
}
2010-02-10 10:56:54 +00:00
else {
2010-03-28 20:46:45 +00:00
# ifdef CHAT_DEBUG
2011-05-04 20:52:45 +00:00
std : : cerr < < " We have no avatar yet: Doing nothing " < < std : : endl ;
2010-03-28 20:46:45 +00:00
# endif
2010-02-10 10:56:54 +00:00
}
2009-01-30 19:52:47 +00:00
}
2010-04-24 10:33:12 +00:00
void p3ChatService : : sendCustomState ( const std : : string & peer_id ) {
# ifdef CHAT_DEBUG
std : : cerr < < " p3chatservice: sending requested status string for peer " < < peer_id < < std : : endl ;
# endif
2010-07-20 19:45:07 +00:00
RsChatStatusItem * cs = makeOwnCustomStateStringItem ( ) ;
cs - > PeerId ( peer_id ) ;
2010-04-24 10:33:12 +00:00
2010-07-20 19:45:07 +00:00
sendItem ( cs ) ;
2010-04-24 10:33:12 +00:00
}
2010-12-18 19:35:07 +00:00
bool p3ChatService : : loadList ( std : : list < RsItem * > & load )
2009-03-20 20:41:31 +00:00
{
2009-09-29 20:37:20 +00:00
for ( std : : list < RsItem * > : : const_iterator it ( load . begin ( ) ) ; it ! = load . end ( ) ; + + it )
2009-03-20 20:41:31 +00:00
{
2009-09-29 20:37:20 +00:00
RsChatAvatarItem * ai = NULL ;
if ( NULL ! = ( ai = dynamic_cast < RsChatAvatarItem * > ( * it ) ) )
2009-03-20 20:41:31 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-09-29 20:37:20 +00:00
_own_avatar = new AvatarInfo ( ai - > image_data , ai - > image_size ) ;
2010-09-21 00:08:06 +00:00
delete * it ;
continue ;
2009-03-20 20:41:31 +00:00
}
2009-09-29 20:37:20 +00:00
RsChatStatusItem * mitem = NULL ;
2009-03-20 20:41:31 +00:00
2009-09-29 20:37:20 +00:00
if ( NULL ! = ( mitem = dynamic_cast < RsChatStatusItem * > ( * it ) ) )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-03-20 20:41:31 +00:00
2009-09-29 20:37:20 +00:00
_custom_status_string = mitem - > status_string ;
2010-09-21 00:08:06 +00:00
delete * it ;
continue ;
2009-09-29 20:37:20 +00:00
}
2009-03-20 20:41:31 +00:00
2010-09-21 00:08:06 +00:00
RsPrivateChatMsgConfigItem * citem = NULL ;
if ( NULL ! = ( citem = dynamic_cast < RsPrivateChatMsgConfigItem * > ( * it ) ) )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
if ( citem - > chatFlags & RS_CHAT_FLAG_PRIVATE ) {
RsChatMsgItem * ci = new RsChatMsgItem ( ) ;
citem - > get ( ci ) ;
2009-03-20 20:41:31 +00:00
2010-09-21 00:08:06 +00:00
if ( citem - > configFlags & RS_CHATMSG_CONFIGFLAG_INCOMING ) {
privateIncomingList . push_back ( ci ) ;
} else {
privateOutgoingList . push_back ( ci ) ;
}
} else {
// ignore all other items
}
delete * it ;
continue ;
}
2011-12-26 22:43:54 +00:00
RsConfigKeyValueSet * vitem = NULL ;
if ( NULL ! = ( vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ) )
for ( std : : list < RsTlvKeyValue > : : const_iterator kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; + + kit )
if ( kit - > key = = " DEFAULT_NICK_NAME " )
{
std : : cerr < < " Loaded config default nick name for chat: " < < kit - > value < < std : : endl ;
_default_nick_name = kit - > value ;
}
2010-09-21 00:08:06 +00:00
// delete unknown items
2009-09-29 20:37:20 +00:00
delete * it ;
2009-03-20 20:41:31 +00:00
}
return true ;
}
2010-12-18 19:35:07 +00:00
bool p3ChatService : : saveList ( bool & cleanup , std : : list < RsItem * > & list )
2009-03-20 20:41:31 +00:00
{
2010-09-21 00:08:06 +00:00
cleanup = true ;
2009-05-09 00:19:54 +00:00
/* now we create a pqistore, and stream all the msgs into it */
2009-03-20 20:41:31 +00:00
if ( _own_avatar ! = NULL )
{
2009-09-29 20:37:20 +00:00
RsChatAvatarItem * ci = makeOwnAvatarItem ( ) ;
2011-07-09 18:39:34 +00:00
ci - > PeerId ( mLinkMgr - > getOwnId ( ) ) ;
2009-03-20 20:41:31 +00:00
2009-09-29 20:37:20 +00:00
list . push_back ( ci ) ;
2009-03-20 20:41:31 +00:00
}
2010-09-21 17:32:31 +00:00
mChatMtx . lock ( ) ; /****** MUTEX LOCKED *******/
2009-09-29 20:37:20 +00:00
RsChatStatusItem * di = new RsChatStatusItem ;
di - > status_string = _custom_status_string ;
di - > flags = RS_CHAT_FLAG_CUSTOM_STATE ;
2009-03-20 20:41:31 +00:00
2009-09-29 20:37:20 +00:00
list . push_back ( di ) ;
2009-03-20 20:41:31 +00:00
2010-09-21 00:08:06 +00:00
/* save incoming private chat messages */
std : : list < RsChatMsgItem * > : : iterator it ;
for ( it = privateIncomingList . begin ( ) ; it ! = privateIncomingList . end ( ) ; it + + ) {
RsPrivateChatMsgConfigItem * ci = new RsPrivateChatMsgConfigItem ;
ci - > set ( * it , ( * it ) - > PeerId ( ) , RS_CHATMSG_CONFIGFLAG_INCOMING ) ;
list . push_back ( ci ) ;
}
/* save outgoing private chat messages */
for ( it = privateOutgoingList . begin ( ) ; it ! = privateOutgoingList . end ( ) ; it + + ) {
RsPrivateChatMsgConfigItem * ci = new RsPrivateChatMsgConfigItem ;
ci - > set ( * it , ( * it ) - > PeerId ( ) , 0 ) ;
list . push_back ( ci ) ;
}
2011-12-26 22:43:54 +00:00
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv ;
kv . key = " DEFAULT_NICK_NAME " ;
kv . value = _default_nick_name ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
list . push_back ( vitem ) ;
2010-12-18 19:35:07 +00:00
return true ;
2009-09-29 20:37:20 +00:00
}
2010-09-21 00:08:06 +00:00
void p3ChatService : : saveDone ( )
{
/* unlock mutex */
mChatMtx . unlock ( ) ; /****** MUTEX UNLOCKED *******/
}
2009-09-29 20:37:20 +00:00
RsSerialiser * p3ChatService : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsChatSerialiser ) ;
2011-12-26 22:43:54 +00:00
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
2009-09-29 20:37:20 +00:00
return rss ;
2009-03-20 20:41:31 +00:00
}
2010-09-21 00:08:06 +00:00
/*************** pqiMonitor callback ***********************/
void p3ChatService : : statusChange ( const std : : list < pqipeer > & plist )
{
std : : list < pqipeer > : : const_iterator it ;
for ( it = plist . begin ( ) ; it ! = plist . end ( ) ; it + + ) {
if ( it - > state & RS_PEER_S_FRIEND ) {
if ( it - > actions & RS_PEER_CONNECTED ) {
/* send the saved outgoing messages */
bool changed = false ;
if ( privateOutgoingList . size ( ) ) {
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2009-03-20 20:41:31 +00:00
2011-09-29 09:20:09 +00:00
std : : string ownId = mLinkMgr - > getOwnId ( ) ;
2010-09-21 00:08:06 +00:00
std : : list < RsChatMsgItem * > : : iterator cit = privateOutgoingList . begin ( ) ;
while ( cit ! = privateOutgoingList . end ( ) ) {
RsChatMsgItem * c = * cit ;
2007-12-12 01:43:17 +00:00
2010-09-21 00:08:06 +00:00
if ( c - > PeerId ( ) = = it - > id ) {
2011-09-29 09:20:09 +00:00
mHistoryMgr - > addMessage ( false , c - > PeerId ( ) , ownId , c ) ;
2012-01-06 22:17:08 +00:00
checkSizeAndSendMessage_deprecated ( c ) ; // delete item
2010-09-21 00:08:06 +00:00
changed = true ;
2010-10-11 15:52:12 +00:00
cit = privateOutgoingList . erase ( cit ) ;
2010-09-21 00:08:06 +00:00
continue ;
}
cit + + ;
}
} /* UNLOCKED */
if ( changed ) {
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PRIVATE_OUTGOING_CHAT , NOTIFY_TYPE_DEL ) ;
IndicateConfigChanged ( ) ;
}
}
}
}
}
2011-11-23 22:10:37 +00:00
//********************** Chat Lobby Stuff ***********************//
2011-12-29 14:19:53 +00:00
// returns:
2012-01-06 22:17:08 +00:00
// true: the object is not a duplicate and should be used
// false: the object is a duplicate or there is an error, and it should be destroyed.
2011-12-29 14:19:53 +00:00
//
2012-01-06 22:17:08 +00:00
bool p3ChatService : : bounceLobbyObject ( RsChatLobbyBouncingObject * item , const std : : string & peer_id )
2011-11-25 21:31:52 +00:00
{
2011-12-26 14:45:45 +00:00
bool send_challenge = false ;
ChatLobbyId send_challenge_lobby ;
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-11-25 21:31:52 +00:00
2011-12-26 17:39:38 +00:00
locked_printDebugInfo ( ) ; // debug
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Handling ChatLobbyMsg " < < std : : hex < < item - > msg_id < < " , lobby id " < < item - > lobby_id < < " , from peer id " < < peer_id < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
// send upward for display
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it ( _chat_lobbys . find ( item - > lobby_id ) ) ;
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
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 ) ;
2011-11-25 21:31:52 +00:00
2012-01-14 21:09:04 +00:00
time_t now = time ( NULL ) ;
2011-12-26 14:45:45 +00:00
// Adds the peer id to the list of friend participants, even if it's not original msg source
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
if ( peer_id ! = mLinkMgr - > getOwnId ( ) )
lobby . participating_friends . insert ( peer_id ) ;
2011-12-29 14:19:53 +00:00
2012-01-14 21:09:04 +00:00
lobby . nick_names [ item - > nick ] = now ;
2011-12-29 14:19:53 +00:00
2011-12-26 14:45:45 +00:00
// 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!
2011-11-25 21:31:52 +00:00
{
2011-12-26 14:45:45 +00:00
std : : cerr < < " Msg already received at time " < < it2 - > second < < " . Dropping! " < < std : : endl ;
return false ;
}
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 14:45:45 +00:00
std : : cerr < < " Msg already not received already. Adding in cache, and forwarding! " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 14:45:45 +00:00
2012-01-06 22:17:08 +00:00
lobby . msg_cache [ item - > msg_id ] = now ;
lobby . last_activity = now ;
bool is_message = ( NULL ! = dynamic_cast < RsChatLobbyMsgItem * > ( item ) ) ;
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
// Forward to allparticipating friends, except this peer.
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
for ( std : : set < std : : string > : : const_iterator it ( lobby . participating_friends . begin ( ) ) ; it ! = lobby . participating_friends . end ( ) ; + + it )
2011-12-29 14:19:53 +00:00
if ( ( * it ) ! = peer_id & & mLinkMgr - > isOnline ( * it ) )
2011-12-26 14:45:45 +00:00
{
2012-01-06 22:17:08 +00:00
RsChatLobbyBouncingObject * obj2 = item - > duplicate ( ) ; // makes a copy
RsChatItem * item2 = dynamic_cast < RsChatItem * > ( obj2 ) ;
assert ( item2 ! = NULL ) ;
2011-12-26 14:45:45 +00:00
2011-12-29 14:19:53 +00:00
item2 - > PeerId ( * it ) ; // replaces the virtual peer id with the actual destination.
2011-12-26 14:45:45 +00:00
2012-01-06 22:17:08 +00:00
if ( is_message )
checkSizeAndSendMessage ( static_cast < RsChatLobbyMsgItem * > ( item2 ) ) ;
else
sendItem ( item2 ) ;
2011-12-26 14:45:45 +00:00
}
2012-01-06 22:17:08 +00:00
if ( + + lobby . connexion_challenge_count > CONNECTION_CHALLENGE_MAX_COUNT & & now > lobby . last_connexion_challenge_time + CONNECTION_CHALLENGE_MIN_DELAY )
2011-12-26 14:45:45 +00:00
{
lobby . connexion_challenge_count = 0 ;
send_challenge_lobby = item - > lobby_id ;
send_challenge = true ;
2012-01-06 22:17:08 +00:00
lobby . last_connexion_challenge_time = now ;
2011-11-25 21:31:52 +00:00
}
2011-12-26 14:45:45 +00:00
}
if ( send_challenge )
sendConnectionChallenge ( send_challenge_lobby ) ;
2011-11-25 21:31:52 +00:00
return true ;
}
2012-01-06 22:17:08 +00:00
void p3ChatService : : sendLobbyStatusString ( const ChatLobbyId & lobby_id , const std : : string & status_string )
2011-11-23 22:10:37 +00:00
{
2012-01-06 22:17:08 +00:00
sendLobbyStatusItem ( lobby_id , RS_CHAT_LOBBY_EVENT_PEER_STATUS , status_string ) ;
}
void p3ChatService : : sendLobbyStatusPeerLiving ( const ChatLobbyId & lobby_id )
{
std : : string nick ;
getNickNameForChatLobby ( lobby_id , nick ) ;
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
sendLobbyStatusItem ( lobby_id , RS_CHAT_LOBBY_EVENT_PEER_LEFT , nick ) ;
}
void p3ChatService : : sendLobbyStatusNewPeer ( const ChatLobbyId & lobby_id )
{
std : : string nick ;
getNickNameForChatLobby ( lobby_id , nick ) ;
sendLobbyStatusItem ( lobby_id , RS_CHAT_LOBBY_EVENT_PEER_JOINED , nick ) ;
}
void p3ChatService : : sendLobbyStatusItem ( const ChatLobbyId & lobby_id , int type , const std : : string & status_string )
{
RsChatLobbyEventItem item ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
locked_initLobbyBouncableObject ( lobby_id , item ) ;
item . event_type = type ;
item . string1 = status_string ;
}
std : : string ownId = mLinkMgr - > getOwnId ( ) ;
bounceLobbyObject ( & item , ownId ) ;
}
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
void p3ChatService : : locked_initLobbyBouncableObject ( const ChatLobbyId & lobby_id , RsChatLobbyBouncingObject & item )
{
2011-11-25 21:31:52 +00:00
// get a pointer to the info for that chat lobby.
//
2011-12-26 17:39:38 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it ( _chat_lobbys . find ( lobby_id ) ) ;
2011-11-25 21:31:52 +00:00
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 ;
2012-01-06 22:17:08 +00:00
return ;
2011-11-25 21:31:52 +00:00
}
2011-12-26 17:39:38 +00:00
ChatLobbyEntry & lobby ( it - > second ) ;
2011-11-25 21:31:52 +00:00
// chat lobby stuff
//
2012-01-06 22:17:08 +00:00
do
{
item . msg_id = RSRandom : : random_u64 ( ) ;
}
while ( lobby . msg_cache . find ( item . msg_id ) ! = lobby . msg_cache . end ( ) ) ;
2011-12-26 17:39:38 +00:00
2011-11-25 21:31:52 +00:00
item . lobby_id = lobby_id ;
2012-01-06 22:17:08 +00:00
item . nick = lobby . nick_name ;
}
2011-12-28 22:33:37 +00:00
2012-01-06 22:17:08 +00:00
bool p3ChatService : : sendLobbyChat ( const std : : wstring & msg , const ChatLobbyId & lobby_id )
{
# ifdef CHAT_DEBUG
std : : cerr < < " Sending chat lobby message to lobby " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
std : : cerr < < " msg: " < < std : : endl ;
std : : wcerr < < msg < < std : : endl ;
# endif
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
RsChatLobbyMsgItem item ;
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
// gives a random msg id, setup the nickname
locked_initLobbyBouncableObject ( lobby_id , item ) ;
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
// chat msg stuff
//
item . chatFlags = RS_CHAT_FLAG_LOBBY | RS_CHAT_FLAG_PRIVATE ;
item . sendTime = time ( NULL ) ;
item . recvTime = item . sendTime ;
item . message = msg ;
}
2011-11-25 21:31:52 +00:00
2012-01-06 22:17:08 +00:00
bounceLobbyObject ( & item , rsPeers - > getOwnId ( ) ) ;
2011-11-25 21:31:52 +00:00
2011-11-23 22:10:37 +00:00
return true ;
}
2011-11-25 21:31:52 +00:00
2011-12-26 14:45:45 +00:00
void p3ChatService : : handleConnectionChallenge ( RsChatLobbyConnectChallengeItem * item )
{
// Look into message cache of all lobbys to handle the challenge.
//
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 14:45:45 +00:00
std : : cerr < < " p3ChatService::handleConnectionChallenge(): received connexion challenge: " < < std : : endl ;
std : : cerr < < " Challenge code = 0x " < < std : : hex < < item - > challenge_code < < std : : dec < < std : : endl ;
std : : cerr < < " Peer Id = " < < item - > PeerId ( ) < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 14:45:45 +00:00
ChatLobbyId lobby_id ;
bool found = false ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-26 22:43:54 +00:00
for ( std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it ( _chat_lobbys . begin ( ) ) ; it ! = _chat_lobbys . end ( ) & & ! found ; + + it )
2011-12-26 17:39:38 +00:00
for ( std : : map < ChatLobbyMsgId , time_t > : : const_iterator it2 ( it - > second . msg_cache . begin ( ) ) ; it2 ! = it - > second . msg_cache . end ( ) & & ! found ; + + it2 )
{
uint64_t code = makeConnexionChallengeCode ( it - > first , it2 - > first ) ;
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 17:39:38 +00:00
std : : cerr < < " Lobby_id = 0x " < < std : : hex < < it - > first < < " , msg_id = 0x " < < it2 - > first < < " : code = 0x " < < code < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 17:39:38 +00:00
if ( code = = item - > challenge_code )
2011-12-26 14:45:45 +00:00
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 14:45:45 +00:00
std : : cerr < < " Challenge accepted for lobby " < < std : : hex < < it - > first < < " , for chat msg " < < it2 - > first < < std : : dec < < std : : endl ;
std : : cerr < < " Sending connection request to peer " < < item - > PeerId ( ) < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 14:45:45 +00:00
lobby_id = it - > first ;
found = true ;
2011-12-26 22:43:54 +00:00
// also add the peer to the list of participating friends
it - > second . participating_friends . insert ( item - > PeerId ( ) ) ;
2011-12-26 14:45:45 +00:00
}
2011-12-26 17:39:38 +00:00
}
2011-12-26 14:45:45 +00:00
}
2011-12-26 22:43:54 +00:00
if ( found ) // send invitation. As the peer already has the lobby, the invitation will most likely be accepted.
2011-12-26 14:45:45 +00:00
invitePeerToLobby ( lobby_id , item - > PeerId ( ) ) ;
else
std : : cerr < < " Challenge denied: no existing cached msg has matching Id. " < < std : : endl ;
}
void p3ChatService : : sendConnectionChallenge ( ChatLobbyId lobby_id )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 14:45:45 +00:00
std : : cerr < < " Sending connection challenge to friends for lobby 0x " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 14:45:45 +00:00
// look for a msg in cache. Any recent msg is fine.
std : : map < ChatLobbyId , ChatLobbyEntry > : : const_iterator it = _chat_lobbys . find ( lobby_id ) ;
if ( it = = _chat_lobbys . end ( ) )
{
std : : cerr < < " ERROR: sendConnectionChallenge(): could not find lobby 0x " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
return ;
}
time_t now = time ( NULL ) ;
uint64_t code = 0 ;
for ( std : : map < ChatLobbyMsgId , time_t > : : const_iterator it2 ( it - > second . msg_cache . begin ( ) ) ; it2 ! = it - > second . msg_cache . end ( ) ; + + it2 )
2011-12-26 17:39:38 +00:00
if ( it2 - > second + 20 > now ) // any msg not older than 20 seconds is fine.
2011-12-26 14:45:45 +00:00
{
code = makeConnexionChallengeCode ( lobby_id , it2 - > first ) ;
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 17:39:38 +00:00
std : : cerr < < " Using msg id 0x " < < std : : hex < < it2 - > first < < " , challenge code = " < < code < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 17:39:38 +00:00
break ;
2011-12-26 14:45:45 +00:00
}
if ( code = = 0 )
{
std : : cerr < < " No suitable message found in cache. Weird !! " < < std : : endl ;
return ;
}
// Broadcast to all direct friends
std : : list < std : : string > ids ;
mLinkMgr - > getOnlineList ( ids ) ;
for ( std : : list < std : : string > : : const_iterator it ( ids . begin ( ) ) ; it ! = ids . end ( ) ; + + it )
{
RsChatLobbyConnectChallengeItem * item = new RsChatLobbyConnectChallengeItem ;
item - > PeerId ( * it ) ;
item - > challenge_code = code ;
sendItem ( item ) ;
}
}
uint64_t p3ChatService : : makeConnexionChallengeCode ( ChatLobbyId lobby_id , ChatLobbyMsgId msg_id )
{
2011-12-26 17:39:38 +00:00
return ( ( uint64_t ) lobby_id ) ^ ( uint64_t ) msg_id ;
2011-12-26 14:45:45 +00:00
}
2011-11-23 22:10:37 +00:00
void p3ChatService : : getChatLobbyList ( std : : list < ChatLobbyInfo > & linfos )
{
// fill up a dummy list for now.
2011-11-25 21:31:52 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-11-23 22:10:37 +00:00
2011-11-25 21:31:52 +00:00
linfos . clear ( ) ;
2011-11-23 22:10:37 +00:00
2011-11-25 21:31:52 +00:00
for ( std : : map < ChatLobbyId , ChatLobbyEntry > : : const_iterator it ( _chat_lobbys . begin ( ) ) ; it ! = _chat_lobbys . end ( ) ; + + it )
linfos . push_back ( it - > second ) ;
2011-11-23 22:10:37 +00:00
}
void p3ChatService : : invitePeerToLobby ( const ChatLobbyId & lobby_id , const std : : string & peer_id )
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-28 22:36:13 +00:00
std : : cerr < < " Sending invitation to peer " < < peer_id < < " to lobby " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
RsChatLobbyInviteItem * item = new RsChatLobbyInviteItem ;
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( lobby_id ) ;
if ( it = = _chat_lobbys . end ( ) )
{
std : : cerr < < " invitation send: canceled. Lobby " < < lobby_id < < " not found! " < < std : : endl ;
return ;
}
item - > lobby_id = lobby_id ;
item - > lobby_name = it - > second . lobby_name ;
2012-01-14 21:09:04 +00:00
item - > lobby_privacy_level = it - > second . lobby_privacy_level ;
2011-11-26 21:23:31 +00:00
item - > PeerId ( peer_id ) ;
sendItem ( item ) ;
}
void p3ChatService : : handleRecvLobbyInvite ( RsChatLobbyInviteItem * item )
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2012-01-12 20:56:03 +00:00
std : : cerr < < " Received invite to lobby from " < < item - > PeerId ( ) < < " to lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < " , named " < < item - > lobby_name < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
// 1 - store invite in a cache
//
// 1.1 - if the lobby is already setup, add the peer to the communicating peers.
//
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-26 14:45:45 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( item - > lobby_id ) ;
2011-11-26 21:23:31 +00:00
if ( it ! = _chat_lobbys . end ( ) )
{
2012-01-14 21:09:04 +00:00
std : : cerr < < " Lobby already exists. " < < std : : endl ;
std : : cerr < < " privacy levels: " < < item - > lobby_privacy_level < < " vs. " < < it - > second . lobby_privacy_level ;
if ( item - > lobby_privacy_level ! = it - > second . lobby_privacy_level )
{
std : : cerr < < " : Don't match. Cancelling. " < < std : : endl ;
return ;
}
else
std : : cerr < < " : Match! " < < std : : endl ;
std : : cerr < < " Addign new friend " < < item - > PeerId ( ) < < " to lobby. " < < std : : endl ;
2011-12-26 14:45:45 +00:00
it - > second . participating_friends . insert ( item - > PeerId ( ) ) ;
2011-11-26 21:23:31 +00:00
return ;
}
// no, then create a new invitation entry in the cache.
ChatLobbyInvite invite ;
invite . lobby_id = item - > lobby_id ;
invite . peer_id = item - > PeerId ( ) ;
invite . lobby_name = item - > lobby_name ;
2012-01-14 21:09:04 +00:00
invite . lobby_privacy_level = item - > lobby_privacy_level ;
2011-11-26 21:23:31 +00:00
_lobby_invites_queue [ item - > lobby_id ] = invite ;
}
// 2 - notify the gui to ask the user.
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_INVITATION , NOTIFY_TYPE_ADD ) ;
}
2011-11-28 22:36:13 +00:00
void p3ChatService : : getPendingChatLobbyInvites ( std : : list < ChatLobbyInvite > & invites )
{
invites . clear ( ) ;
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
for ( std : : map < ChatLobbyId , ChatLobbyInvite > : : const_iterator it ( _lobby_invites_queue . begin ( ) ) ; it ! = _lobby_invites_queue . end ( ) ; + + it )
invites . push_back ( it - > second ) ;
}
2011-11-26 21:23:31 +00:00
bool p3ChatService : : acceptLobbyInvite ( const ChatLobbyId & lobby_id )
{
2011-12-04 14:31:48 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-11-26 21:23:31 +00:00
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 14:31:48 +00:00
std : : cerr < < " Accepting chat lobby " < < lobby_id < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
std : : map < ChatLobbyId , ChatLobbyInvite > : : iterator it = _lobby_invites_queue . find ( lobby_id ) ;
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
if ( it = = _lobby_invites_queue . end ( ) )
{
std : : cerr < < " (EE) lobby invite not in cache!! " < < std : : endl ;
return false ;
}
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
if ( _chat_lobbys . find ( lobby_id ) ! = _chat_lobbys . end ( ) )
{
std : : cerr < < " (II) Lobby already exists. Weird. " < < std : : endl ;
return true ;
}
2011-11-26 21:23:31 +00:00
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 14:31:48 +00:00
std : : cerr < < " Creating new Lobby entry. " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
ChatLobbyEntry entry ;
entry . participating_friends . insert ( it - > second . peer_id ) ;
2012-01-14 21:09:04 +00:00
entry . lobby_privacy_level = it - > second . lobby_privacy_level ;
2012-01-06 22:17:08 +00:00
entry . nick_name = _default_nick_name ;
2011-12-04 14:31:48 +00:00
entry . lobby_id = lobby_id ;
entry . lobby_name = it - > second . lobby_name ;
entry . virtual_peer_id = makeVirtualPeerId ( lobby_id ) ;
2011-12-26 14:45:45 +00:00
entry . connexion_challenge_count = 0 ;
2012-01-06 22:17:08 +00:00
entry . last_activity = time ( NULL ) ;
entry . last_connexion_challenge_time = time ( NULL ) ;
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
_lobby_ids [ entry . virtual_peer_id ] = lobby_id ;
_chat_lobbys [ lobby_id ] = entry ;
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
_lobby_invites_queue . erase ( it ) ; // remove the invite from cache.
// we should also send a message to the lobby to tell we're here.
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 14:31:48 +00:00
std : : cerr < < " Pushing new msg item to incoming msgs. " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-04 14:31:48 +00:00
RsChatLobbyMsgItem * item = new RsChatLobbyMsgItem ;
item - > lobby_id = entry . lobby_id ;
item - > msg_id = 0 ;
2011-12-26 14:45:45 +00:00
item - > nick = " Lobby management " ;
2011-12-04 14:31:48 +00:00
item - > message = std : : wstring ( L " Welcome to chat lobby " ) ;
item - > PeerId ( entry . virtual_peer_id ) ;
item - > chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_LOBBY ;
privateIncomingList . push_back ( item ) ;
}
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-04 14:31:48 +00:00
std : : cerr < < " Notifying of new recvd msg. " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-04 14:31:48 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_PRIVATE_INCOMING_CHAT , NOTIFY_TYPE_ADD ) ;
2012-01-12 00:13:25 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_ADD ) ;
2011-11-28 22:36:13 +00:00
2011-12-07 00:12:17 +00:00
// send AKN item
2012-01-06 22:17:08 +00:00
sendLobbyStatusNewPeer ( lobby_id ) ;
2011-12-26 14:45:45 +00:00
2011-11-26 21:23:31 +00:00
return true ;
}
2011-12-04 14:31:48 +00:00
std : : string p3ChatService : : makeVirtualPeerId ( ChatLobbyId lobby_id )
{
std : : ostringstream os ;
os < < " Chat Lobby 0x " < < std : : hex < < lobby_id < < std : : dec ;
return os . str ( ) ;
}
2011-11-26 21:23:31 +00:00
void p3ChatService : : denyLobbyInvite ( const ChatLobbyId & lobby_id )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-26 21:23:31 +00:00
std : : cerr < < " Denying chat lobby invite to " < < lobby_id < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
std : : map < ChatLobbyId , ChatLobbyInvite > : : iterator it = _lobby_invites_queue . find ( lobby_id ) ;
if ( it = = _lobby_invites_queue . end ( ) )
{
std : : cerr < < " (EE) lobby invite not in cache!! " < < std : : endl ;
return ;
}
_lobby_invites_queue . erase ( it ) ;
}
2012-01-07 19:52:58 +00:00
bool p3ChatService : : joinPublicChatLobby ( const ChatLobbyId & lobby_id )
{
# ifdef CHAT_DEBUG
std : : cerr < < " Joining public chat lobby " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
# endif
std : : list < std : : string > invited_friends ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
// create a unique id.
//
std : : map < ChatLobbyId , PublicChatLobbyRecord > : : const_iterator it ( _public_lobbies . find ( lobby_id ) ) ;
if ( it = = _public_lobbies . end ( ) )
{
std : : cerr < < " lobby is not a known public chat lobby. Sorry! " < < std : : endl ;
return false ;
}
# ifdef CHAT_DEBUG
std : : cerr < < " lobby found. Initiating join sequence... " < < std : : endl ;
# endif
if ( _chat_lobbys . find ( lobby_id ) ! = _chat_lobbys . end ( ) )
{
std : : cerr < < " lobby already in participating list. Returning! " < < std : : endl ;
return true ;
}
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-07 19:52:58 +00:00
std : : cerr < < " Creating new lobby entry. " < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-07 19:52:58 +00:00
ChatLobbyEntry entry ;
entry . lobby_privacy_level = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ;
entry . participating_friends . clear ( ) ;
entry . nick_name = _default_nick_name ;
entry . lobby_id = lobby_id ;
entry . lobby_name = it - > second . lobby_name ;
entry . virtual_peer_id = makeVirtualPeerId ( lobby_id ) ;
entry . connexion_challenge_count = 0 ;
entry . last_activity = time ( NULL ) ;
entry . last_connexion_challenge_time = time ( NULL ) ;
_lobby_ids [ entry . virtual_peer_id ] = lobby_id ;
for ( std : : set < std : : string > : : const_iterator it2 ( it - > second . participating_friends . begin ( ) ) ; it2 ! = it - > second . participating_friends . end ( ) ; + + it2 )
2012-01-12 20:56:03 +00:00
{
2012-01-07 19:52:58 +00:00
invited_friends . push_back ( * it2 ) ;
2012-01-12 20:56:03 +00:00
entry . participating_friends . insert ( * it2 ) ;
}
_chat_lobbys [ lobby_id ] = entry ;
2012-01-07 19:52:58 +00:00
}
for ( std : : list < std : : string > : : const_iterator it ( invited_friends . begin ( ) ) ; it ! = invited_friends . end ( ) ; + + it )
invitePeerToLobby ( lobby_id , * it ) ;
2012-01-12 00:13:25 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_ADD ) ;
2012-01-12 20:56:03 +00:00
sendLobbyStatusNewPeer ( lobby_id ) ;
2012-01-12 00:13:25 +00:00
2012-01-07 19:52:58 +00:00
return true ;
}
2012-01-06 22:17:08 +00:00
ChatLobbyId p3ChatService : : createChatLobby ( const std : : string & lobby_name , const std : : list < std : : string > & invited_friends , uint32_t privacy_level )
2011-11-26 21:23:31 +00:00
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-26 21:23:31 +00:00
std : : cerr < < " Creating a new Chat lobby !! " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
ChatLobbyId lobby_id ;
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
// create a unique id.
//
do { lobby_id = RSRandom : : random_u64 ( ) ; } while ( _chat_lobbys . find ( lobby_id ) ! = _chat_lobbys . end ( ) ) ;
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-26 21:23:31 +00:00
std : : cerr < < " New (unique) ID: " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-26 21:23:31 +00:00
ChatLobbyEntry entry ;
2012-01-06 22:17:08 +00:00
entry . lobby_privacy_level = privacy_level ;
2011-11-26 21:23:31 +00:00
entry . participating_friends . clear ( ) ;
2011-12-26 14:45:45 +00:00
entry . nick_name = _default_nick_name ; // to be changed. For debug only!!
2011-11-26 21:23:31 +00:00
entry . lobby_id = lobby_id ;
entry . lobby_name = lobby_name ;
2011-12-04 14:31:48 +00:00
entry . virtual_peer_id = makeVirtualPeerId ( lobby_id ) ;
2011-12-26 14:45:45 +00:00
entry . connexion_challenge_count = 0 ;
2012-01-06 22:17:08 +00:00
entry . last_activity = time ( NULL ) ;
entry . last_connexion_challenge_time = time ( NULL ) ;
2011-11-26 21:23:31 +00:00
2011-12-04 14:31:48 +00:00
_lobby_ids [ entry . virtual_peer_id ] = lobby_id ;
2011-11-26 21:23:31 +00:00
_chat_lobbys [ lobby_id ] = entry ;
}
for ( std : : list < std : : string > : : const_iterator it ( invited_friends . begin ( ) ) ; it ! = invited_friends . end ( ) ; + + it )
invitePeerToLobby ( lobby_id , * it ) ;
2011-11-27 21:46:49 +00:00
2012-01-12 00:13:25 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_ADD ) ;
2011-11-27 21:46:49 +00:00
return lobby_id ;
2011-11-23 22:10:37 +00:00
}
2011-12-27 13:47:37 +00:00
void p3ChatService : : handleFriendUnsubscribeLobby ( RsChatLobbyUnsubscribeItem * item )
{
2012-01-12 00:13:25 +00:00
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( item - > lobby_id ) ;
2011-12-27 13:47:37 +00:00
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2012-01-12 00:13:25 +00:00
std : : cerr < < " Received unsubscribed to lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < " , from friend " < < item - > PeerId ( ) < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-27 13:47:37 +00:00
2012-01-12 00:13:25 +00:00
if ( it = = _chat_lobbys . end ( ) )
2011-12-27 13:47:37 +00:00
{
2012-01-12 00:13:25 +00:00
std : : cerr < < " Chat lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < " does not exist ! Can't unsubscribe friend! " < < std : : endl ;
return ;
}
for ( std : : set < std : : string > : : iterator it2 ( it - > second . participating_friends . begin ( ) ) ; it2 ! = it - > second . participating_friends . end ( ) ; + + it2 )
if ( * it2 = = item - > PeerId ( ) )
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2012-01-12 00:13:25 +00:00
std : : cerr < < " removing peer id " < < item - > PeerId ( ) < < " from participant list of lobby " < < std : : hex < < item - > lobby_id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2012-01-12 00:13:25 +00:00
it - > second . participating_friends . erase ( it2 ) ;
break ;
}
}
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_MOD ) ;
2011-12-27 13:47:37 +00:00
}
2011-11-27 21:04:10 +00:00
void p3ChatService : : unsubscribeChatLobby ( const ChatLobbyId & id )
{
2011-12-28 22:33:37 +00:00
// send AKN item
2012-01-06 22:17:08 +00:00
sendLobbyStatusPeerLiving ( id ) ;
2011-12-27 13:47:37 +00:00
{
2011-12-28 22:33:37 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 13:47:37 +00:00
2011-12-28 22:33:37 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( id ) ;
2011-12-27 13:47:37 +00:00
2011-12-28 22:33:37 +00:00
if ( it = = _chat_lobbys . end ( ) )
{
std : : cerr < < " Chat lobby " < < id < < " does not exist ! Can't unsubscribe! " < < std : : endl ;
return ;
}
2011-12-27 13:47:37 +00:00
2011-12-28 22:33:37 +00:00
// send a lobby leaving packet to all friends
2011-12-27 13:47:37 +00:00
2011-12-28 22:33:37 +00:00
for ( std : : set < std : : string > : : const_iterator it2 ( it - > second . participating_friends . begin ( ) ) ; it2 ! = it - > second . participating_friends . end ( ) ; + + it2 )
2011-12-27 13:47:37 +00:00
{
2011-12-28 22:33:37 +00:00
RsChatLobbyUnsubscribeItem * item = new RsChatLobbyUnsubscribeItem ;
item - > lobby_id = id ;
item - > PeerId ( * it2 ) ;
2012-01-12 21:51:57 +00:00
# ifdef CHAT_DEBUG
2012-01-06 22:17:08 +00:00
std : : cerr < < " Sending unsubscribe item to friend " < < * it2 < < std : : endl ;
2012-01-12 21:51:57 +00:00
# endif
2012-01-06 22:17:08 +00:00
2011-12-28 22:33:37 +00:00
sendItem ( item ) ;
2011-12-27 13:47:37 +00:00
}
2011-12-28 22:33:37 +00:00
// remove lobby information
_chat_lobbys . erase ( it ) ;
for ( std : : map < std : : string , ChatLobbyId > : : iterator it2 ( _lobby_ids . begin ( ) ) ; it2 ! = _lobby_ids . end ( ) ; + + it2 )
if ( it2 - > second = = id )
{
_lobby_ids . erase ( it2 ) ;
break ;
}
}
2012-01-12 00:13:25 +00:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_CHAT_LOBBY_LIST , NOTIFY_TYPE_DEL ) ;
2011-12-27 13:47:37 +00:00
// done!
2011-11-27 21:04:10 +00:00
}
2011-12-26 22:43:54 +00:00
bool p3ChatService : : setDefaultNickNameForChatLobby ( const std : : string & nick )
{
_default_nick_name = nick ;
IndicateConfigChanged ( ) ;
return true ;
}
bool p3ChatService : : getDefaultNickNameForChatLobby ( std : : string & nick )
{
nick = _default_nick_name ;
return true ;
}
2011-11-27 21:04:10 +00:00
bool p3ChatService : : getNickNameForChatLobby ( const ChatLobbyId & lobby_id , std : : string & nick )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-27 21:04:10 +00:00
std : : cerr < < " getting nickname for chat lobby " < < std : : hex < < lobby_id < < std : : dec < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-27 21:04:10 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( lobby_id ) ;
if ( it = = _chat_lobbys . end ( ) )
{
std : : cerr < < " (EE) lobby does not exist!! " < < std : : endl ;
return false ;
}
nick = it - > second . nick_name ;
return true ;
}
bool p3ChatService : : setNickNameForChatLobby ( const ChatLobbyId & lobby_id , const std : : string & nick )
{
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-11-27 21:04:10 +00:00
std : : cerr < < " Changing nickname for chat lobby " < < std : : hex < < lobby_id < < std : : dec < < " to " < < nick < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-11-27 21:04:10 +00:00
std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . find ( lobby_id ) ;
if ( it = = _chat_lobbys . end ( ) )
{
std : : cerr < < " (EE) lobby does not exist!! " < < std : : endl ;
return false ;
}
it - > second . nick_name = nick ;
return true ;
}
2011-12-26 22:43:54 +00:00
void p3ChatService : : cleanLobbyCaches ( )
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2011-12-26 22:43:54 +00:00
std : : cerr < < " Cleaning chat lobby caches. " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 22:43:54 +00:00
RsStackMutex stack ( mChatMtx ) ; /********** STACK LOCKED MTX ******/
time_t now = time ( NULL ) ;
2012-01-14 21:09:04 +00:00
// 1 - clean cache of all lobbies and participating nicknames.
//
2011-12-26 22:43:54 +00:00
for ( std : : map < ChatLobbyId , ChatLobbyEntry > : : iterator it = _chat_lobbys . begin ( ) ; it ! = _chat_lobbys . end ( ) ; + + it )
2012-01-14 21:09:04 +00:00
{
2011-12-26 22:43:54 +00:00
for ( std : : map < ChatLobbyMsgId , time_t > : : iterator it2 ( it - > second . msg_cache . begin ( ) ) ; it2 ! = it - > second . msg_cache . end ( ) ; )
if ( it2 - > second + MAX_KEEP_MSG_RECORD < now )
{
2011-12-27 15:35:43 +00:00
# ifdef CHAT_DEBUG
2012-01-14 21:09:04 +00:00
std : : cerr < < " removing old msg 0x " < < std : : hex < < it2 - > first < < " , time= " < < std : : dec < < now - it2 - > second < < " secs ago " < < std : : endl ;
2011-12-27 15:35:43 +00:00
# endif
2011-12-26 22:43:54 +00:00
std : : map < ChatLobbyMsgId , time_t > : : iterator tmp ( it2 ) ;
+ + tmp ;
it - > second . msg_cache . erase ( it2 ) ;
it2 = tmp ;
}
else
+ + it2 ;
2012-01-06 22:17:08 +00:00
2012-01-14 21:09:04 +00:00
for ( std : : map < std : : string , time_t > : : iterator it2 ( it - > second . nick_names . begin ( ) ) ; it2 ! = it - > second . nick_names . end ( ) ; )
if ( it2 - > second + MAX_KEEP_INACTIVE_NICKNAME < now )
{
# ifdef CHAT_DEBUG
std : : cerr < < " removing inactive nickname 0x " < < std : : hex < < it2 - > first < < " , time= " < < std : : dec < < now - it2 - > second < < " secs ago " < < std : : endl ;
# endif
std : : map < std : : string , time_t > : : iterator tmp ( it2 ) ;
+ + tmp ;
it - > second . nick_names . erase ( it2 ) ;
it2 = tmp ;
}
else
+ + it2 ;
}
// 2 - clean deprecated public chat lobby records
//
for ( std : : map < ChatLobbyId , PublicChatLobbyRecord > : : iterator it ( _public_lobbies . begin ( ) ) ; it ! = _public_lobbies . end ( ) ; )
if ( it - > second . last_report_time + MAX_KEEP_PUBLIC_LOBBY_RECORD < now ) // this lobby record is too late.
{
# ifdef CHAT_DEBUG
std : : cerr < < " removing old public lobby record 0x " < < std : : hex < < it - > first < < " , time= " < < std : : dec < < now - it - > second . last_report_time < < " secs ago " < < std : : endl ;
# endif
std : : map < ChatLobbyMsgId , PublicChatLobbyRecord > : : iterator tmp ( it ) ;
+ + tmp ;
_public_lobbies . erase ( it ) ;
it = tmp ;
}
else
+ + it ;
2011-12-26 22:43:54 +00:00
}
2012-01-14 21:09:04 +00:00