llimview.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:18k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file LLIMMgr.h
  3.  * @brief Container for Instant Messaging
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLIMVIEW_H
  33. #define LL_LLIMVIEW_H
  34. #include "lldockablefloater.h"
  35. #include "llinstantmessage.h"
  36. #include "lllogchat.h"
  37. #include "llvoicechannel.h"
  38. class LLFriendObserver;
  39. class LLCallDialogManager;
  40. class LLIMSpeakerMgr;
  41. class LLIMModel :  public LLSingleton<LLIMModel>
  42. {
  43. public:
  44. struct LLIMSession
  45. {
  46. typedef enum e_session_type
  47. {   // for now we have 4 predefined types for a session
  48. P2P_SESSION,
  49. GROUP_SESSION,
  50. ADHOC_SESSION,
  51. AVALINE_SESSION,
  52. } SType;
  53. LLIMSession(const LLUUID& session_id, const std::string& name, 
  54. const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids, bool voice);
  55. virtual ~LLIMSession();
  56. void sessionInitReplyReceived(const LLUUID& new_session_id);
  57. void addMessagesFromHistory(const std::list<LLSD>& history);
  58. void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time);
  59. void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
  60. /** @deprecated */
  61. static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
  62. bool isAdHoc();
  63. bool isP2P();
  64. bool isOtherParticipantAvaline();
  65. bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
  66. bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
  67. bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
  68. bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
  69. //*TODO make private
  70. /** ad-hoc sessions involve sophisticated chat history file naming schemes */
  71. void buildHistoryFileName();
  72. //*TODO make private
  73. static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
  74. LLUUID mSessionID;
  75. std::string mName;
  76. EInstantMessage mType;
  77. SType mSessionType;
  78. LLUUID mOtherParticipantID;
  79. std::vector<LLUUID> mInitialTargetIDs;
  80. std::string mHistoryFileName;
  81. // connection to voice channel state change signal
  82. boost::signals2::connection mVoiceChannelStateChangeConnection;
  83. //does NOT include system messages and agent's messages
  84. S32 mParticipantUnreadMessageCount;
  85. // does include all incoming messages
  86. S32 mNumUnread;
  87. std::list<LLSD> mMsgs;
  88. LLVoiceChannel* mVoiceChannel;
  89. LLIMSpeakerMgr* mSpeakers;
  90. bool mSessionInitialized;
  91. //true if calling back the session URI after the session has closed is possible.
  92. //Currently this will be false only for PSTN P2P calls.
  93. bool mCallBackEnabled;
  94. bool mTextIMPossible;
  95. bool mOtherParticipantIsAvatar;
  96. bool mStartCallOnInitialize;
  97. //if IM session is created for a voice call
  98. bool mStartedAsIMCall;
  99. };
  100. LLIMModel();
  101. //we should control the currently active session
  102. LLUUID mActiveSessionID;
  103. void setActiveSessionID(const LLUUID& session_id);
  104. void resetActiveSessionID() { mActiveSessionID.setNull(); }
  105. LLUUID getActiveSessionID() { return mActiveSessionID; }
  106. /** Session id to session object */
  107. std::map<LLUUID, LLIMSession*> mId2SessionMap;
  108. typedef boost::signals2::signal<void(const LLSD&)> session_signal_t;
  109. typedef boost::function<void(const LLSD&)> session_callback_t;
  110. session_signal_t mNewMsgSignal;
  111. session_signal_t mNoUnreadMsgsSignal;
  112. /** 
  113.  * Find an IM Session corresponding to session_id
  114.  * Returns NULL if the session does not exist
  115.  */
  116. LLIMSession* findIMSession(const LLUUID& session_id) const;
  117. /** 
  118.  * Find an Ad-Hoc IM Session with specified participants
  119.  * @return first found Ad-Hoc session or NULL if the session does not exist
  120.  */
  121. LLIMSession* findAdHocIMSession(const std::vector<LLUUID>& ids);
  122. /**
  123.  * Rebind session data to a new session id.
  124.  */
  125. void processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id);
  126. boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); }
  127. boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); }
  128. /**
  129.  * Create new session object in a model
  130.  * @param name session name should not be empty, will return false if empty
  131.  */
  132. bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, 
  133. const std::vector<LLUUID>& ids, bool voice = false);
  134. bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
  135. const LLUUID& other_participant_id, bool voice = false);
  136. /**
  137.  * Remove all session data associated with a session specified by session_id
  138.  */
  139. bool clearSession(const LLUUID& session_id);
  140. /**
  141.  * Populate supplied std::list with messages starting from index specified by start_index
  142.  */
  143. void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
  144. /**
  145.  * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id
  146.  * and also saved into a file if log2file is specified.
  147.  * It sends new message signal for each added message.
  148.  */
  149. bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true);
  150. /**
  151.  * Similar to addMessage(...) above but won't send a signal about a new message added
  152.  */
  153. LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
  154. const std::string& utf8_text, bool log2file = true);
  155. /**
  156.  * Add a system message to an IM Model
  157.  */
  158. bool proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text);
  159. /**
  160.  * Get a session's name. 
  161.  * For a P2P chat - it's an avatar's name, 
  162.  * For a group chat - it's a group's name
  163.  * For an ad-hoc chat - is received from the server and is in a from of "<Avatar's name> conference"
  164.  */
  165. const std::string& getName(const LLUUID& session_id) const;
  166. /** 
  167.  * Get number of unread messages in a session with session_id
  168.  * Returns -1 if the session with session_id doesn't exist
  169.  */
  170. const S32 getNumUnread(const LLUUID& session_id) const;
  171. /**
  172.  * Get uuid of other participant in a session with session_id
  173.  * Returns LLUUID::null if the session doesn't exist
  174.  *
  175.    * *TODO what to do with other participants in ad-hoc and group chats?
  176.  */
  177. const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
  178. /**
  179.  * Get type of a session specified by session_id
  180.  * Returns EInstantMessage::IM_COUNT if the session does not exist
  181.  */
  182. EInstantMessage getType(const LLUUID& session_id) const;
  183. /**
  184.  * Get voice channel for the session specified by session_id
  185.  * Returns NULL if the session does not exist
  186.  */
  187. LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
  188. /**
  189. * Get im speaker manager for the session specified by session_id
  190. * Returns NULL if the session does not exist
  191. */
  192. LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
  193. const std::string& getHistoryFileName(const LLUUID& session_id) const;
  194. static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id);
  195. static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
  196.   const std::vector<LLUUID>& ids, EInstantMessage dialog);
  197. static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing);
  198. static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
  199. const LLUUID& other_participant_id, EInstantMessage dialog);
  200. void testMessages();
  201. /**
  202.  * Saves an IM message into a file
  203.  */
  204. bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
  205. private:
  206. /**
  207.  * Add message to a list of message associated with session specified by session_id
  208.  */
  209. bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); 
  210. /**
  211.  * Save an IM message into a file
  212.  */
  213. bool logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
  214. };
  215. class LLIMSessionObserver
  216. {
  217. public:
  218. virtual ~LLIMSessionObserver() {}
  219. virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
  220. virtual void sessionRemoved(const LLUUID& session_id) = 0;
  221. virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
  222. };
  223. class LLIMMgr : public LLSingleton<LLIMMgr>
  224. {
  225. friend class LLIMModel;
  226. public:
  227. enum EInvitationType
  228. {
  229. INVITATION_TYPE_INSTANT_MESSAGE = 0,
  230. INVITATION_TYPE_VOICE = 1,
  231. INVITATION_TYPE_IMMEDIATE = 2
  232. };
  233. LLIMMgr();
  234. virtual ~LLIMMgr() {};
  235. // Add a message to a session. The session can keyed to sesion id
  236. // or agent id.
  237. void addMessage(const LLUUID& session_id,
  238. const LLUUID& target_id,
  239. const std::string& from,
  240. const std::string& msg,
  241. const std::string& session_name = LLStringUtil::null,
  242. EInstantMessage dialog = IM_NOTHING_SPECIAL,
  243. U32 parent_estate_id = 0,
  244. const LLUUID& region_id = LLUUID::null,
  245. const LLVector3& position = LLVector3::zero,
  246. bool link_name = false);
  247. void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
  248. // This adds a session to the talk view. The name is the local
  249. // name of the session, dialog specifies the type of
  250. // session. Since sessions can be keyed off of first recipient or
  251. // initiator, the session can be matched against the id
  252. // provided. If the session exists, it is brought forward.  This
  253. // method accepts a group id or an agent id. Specifying id = NULL
  254. // results in an im session to everyone. Returns the uuid of the
  255. // session.
  256. LLUUID addSession(const std::string& name,
  257.   EInstantMessage dialog,
  258.   const LLUUID& other_participant_id, bool voice = false);
  259. // Adds a session using a specific group of starting agents
  260. // the dialog type is assumed correct. Returns the uuid of the session.
  261. LLUUID addSession(const std::string& name,
  262.   EInstantMessage dialog,
  263.   const LLUUID& other_participant_id,
  264.   const LLDynamicArray<LLUUID>& ids, bool voice = false);
  265. /**
  266.  * Creates a P2P session with the requisite handle for responding to voice calls.
  267.  * 
  268.  * @param name session name, cannot be null
  269.  * @param caller_uri - sip URI of caller. It should be always be passed into the method to avoid
  270.  * incorrect working of LLVoiceChannel instances. See EXT-2985.
  271.  */
  272. LLUUID addP2PSession(const std::string& name,
  273.   const LLUUID& other_participant_id,
  274.   const std::string& voice_session_handle,
  275.   const std::string& caller_uri);
  276. /**
  277.  * Leave the session with session id. Send leave session notification
  278.  * to the server and removes all associated session data
  279.  * @return false if the session with specified id was not exist
  280.  */
  281. bool leaveSession(const LLUUID& session_id);
  282. void inviteToSession(
  283. const LLUUID& session_id, 
  284. const std::string& session_name, 
  285. const LLUUID& caller, 
  286. const std::string& caller_name,
  287. EInstantMessage type,
  288. EInvitationType inv_type, 
  289. const std::string& session_handle = LLStringUtil::null,
  290. const std::string& session_uri = LLStringUtil::null);
  291. void processIMTypingStart(const LLIMInfo* im_info);
  292. void processIMTypingStop(const LLIMInfo* im_info);
  293. // automatically start a call once the session has initialized
  294. void autoStartCallOnStartup(const LLUUID& session_id);
  295. // Calc number of all unread IMs
  296. S32 getNumberOfUnreadIM();
  297. /**
  298.  * Calculates number of unread IMs from real participants in all stored sessions
  299.  */
  300. S32 getNumberOfUnreadParticipantMessages();
  301. // This method is used to go through all active sessions and
  302. // disable all of them. This method is usally called when you are
  303. // forced to log out or similar situations where you do not have a
  304. // good connection.
  305. void disconnectAllSessions();
  306. BOOL hasSession(const LLUUID& session_id);
  307. static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
  308. void clearPendingInvitation(const LLUUID& session_id);
  309. void processAgentListUpdates(const LLUUID& session_id, const LLSD& body);
  310. LLSD getPendingAgentListUpdates(const LLUUID& session_id);
  311. void addPendingAgentListUpdates(
  312. const LLUUID& sessioN_id,
  313. const LLSD& updates);
  314. void clearPendingAgentListUpdates(const LLUUID& session_id);
  315. void addSessionObserver(LLIMSessionObserver *);
  316. void removeSessionObserver(LLIMSessionObserver *);
  317. //show error statuses to the user
  318. void showSessionStartError(const std::string& error_string, const LLUUID session_id);
  319. void showSessionEventError(const std::string& event_string, const std::string& error_string, const LLUUID session_id);
  320. void showSessionForceClose(const std::string& reason, const LLUUID session_id);
  321. static bool onConfirmForceCloseError(const LLSD& notification, const LLSD& response);
  322. /**
  323.  * Start call in a session
  324.  * @return false if voice channel doesn't exist
  325.  **/
  326. bool startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction = LLVoiceChannel::OUTGOING_CALL);
  327. /**
  328.  * End call in a session
  329.  * @return false if voice channel doesn't exist
  330.  **/
  331. bool endCall(const LLUUID& session_id);
  332. bool isVoiceCall(const LLUUID& session_id);
  333. private:
  334. /**
  335.  * Remove data associated with a particular session specified by session_id
  336.  */
  337. void removeSession(const LLUUID& session_id);
  338. // This simple method just iterates through all of the ids, and
  339. // prints a simple message if they are not online. Used to help
  340. // reduce 'hello' messages to the linden employees unlucky enough
  341. // to have their calling card in the default inventory.
  342. void noteOfflineUsers(const LLUUID& session_id, const LLDynamicArray<LLUUID>& ids);
  343. void noteMutedUsers(const LLUUID& session_id, const LLDynamicArray<LLUUID>& ids);
  344. void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
  345. static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group);
  346. void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
  347. void notifyObserverSessionRemoved(const LLUUID& session_id);
  348. void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
  349. private:
  350. typedef std::list <LLIMSessionObserver *> session_observers_list_t;
  351. session_observers_list_t mSessionObservers;
  352. LLSD mPendingInvitations;
  353. LLSD mPendingAgentListUpdates;
  354. };
  355. class LLCallDialogManager : public LLInitClass<LLCallDialogManager>
  356. {
  357. public:
  358. LLCallDialogManager();
  359. ~LLCallDialogManager();
  360. static void initClass();
  361. static void onVoiceChannelChanged(const LLUUID &session_id);
  362. static void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction, bool ended_by_agent);
  363. protected:
  364. static std::string sPreviousSessionlName;
  365. static LLIMModel::LLIMSession::SType sPreviousSessionType;
  366. static std::string sCurrentSessionlName;
  367. static LLIMModel::LLIMSession* sSession;
  368. static LLVoiceChannel::EState sOldState;
  369. };
  370. class LLCallDialog : public LLDockableFloater
  371. {
  372. public:
  373. LLCallDialog(const LLSD& payload);
  374. ~LLCallDialog() {}
  375. virtual BOOL postBuild();
  376. // check timer state
  377. /*virtual*/ void draw();
  378. /*virtual*/ void onOpen(const LLSD& key);
  379. protected:
  380. // lifetime timer for a notification
  381. LLTimer mLifetimeTimer;
  382. // notification's lifetime in seconds
  383. S32 mLifetime;
  384. static const S32 DEFAULT_LIFETIME = 5;
  385. virtual bool lifetimeHasExpired();
  386. virtual void onLifetimeExpired();
  387. virtual void getAllowedRect(LLRect& rect);
  388. /**
  389.  * Sets icon depend on session.
  390.  *
  391.  * If passed session_id is a group id group icon will be shown, otherwise avatar icon for participant_id
  392.  *
  393.  * @param session_id - UUID of session
  394.  * @param participant_id - UUID of other participant
  395.  */
  396. void setIcon(const LLSD& session_id, const LLSD& participant_id);
  397. LLSD mPayload;
  398. };
  399. class LLIncomingCallDialog : public LLCallDialog
  400. {
  401. public:
  402. LLIncomingCallDialog(const LLSD& payload);
  403. /*virtual*/ BOOL postBuild();
  404. /*virtual*/ void onOpen(const LLSD& key);
  405. static void onAccept(void* user_data);
  406. static void onReject(void* user_data);
  407. static void onStartIM(void* user_data);
  408. private:
  409. /*virtual*/ void onLifetimeExpired();
  410. void processCallResponse(S32 response);
  411. };
  412. class LLOutgoingCallDialog : public LLCallDialog
  413. {
  414. public:
  415. LLOutgoingCallDialog(const LLSD& payload);
  416. /*virtual*/ BOOL postBuild();
  417. void show(const LLSD& key);
  418. static void onCancel(void* user_data);
  419. static const LLUUID OCD_KEY;
  420. private:
  421. // hide all text boxes
  422. void hideAllText();
  423. };
  424. // Globals
  425. extern LLIMMgr *gIMMgr;
  426. #endif  // LL_LLIMView_H