aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llimview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llimview.cpp')
-rw-r--r--linden/indra/newview/llimview.cpp481
1 files changed, 223 insertions, 258 deletions
diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp
index 20de43e..790e20b 100644
--- a/linden/indra/newview/llimview.cpp
+++ b/linden/indra/newview/llimview.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 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 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 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -97,6 +98,96 @@ std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap;
97// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); 98// return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
98//} 99//}
99 100
101class LLViewerChatterBoxInvitationAcceptResponder :
102 public LLHTTPClient::Responder
103{
104public:
105 LLViewerChatterBoxInvitationAcceptResponder(
106 const LLUUID& session_id,
107 LLIMMgr::EInvitationType invitation_type)
108 {
109 mSessionID = session_id;
110 mInvitiationType = invitation_type;
111 }
112
113 void result(const LLSD& content)
114 {
115 if ( gIMMgr)
116 {
117 LLFloaterIMPanel* floaterp =
118 gIMMgr->findFloaterBySession(mSessionID);
119
120 if (floaterp)
121 {
122 //we've accepted our invitation
123 //and received a list of agents that were
124 //currently in the session when the reply was sent
125 //to us. Now, it is possible that there were some agents
126 //to slip in/out between when that message was sent to us
127 //and now.
128
129 //the agent list updates we've received have been
130 //accurate from the time we were added to the session
131 //but unfortunately, our base that we are receiving here
132 //may not be the most up to date. It was accurate at
133 //some point in time though.
134 floaterp->setSpeakers(content);
135
136 //we now have our base of users in the session
137 //that was accurate at some point, but maybe not now
138 //so now we apply all of the udpates we've received
139 //in case of race conditions
140 floaterp->updateSpeakersList(
141 gIMMgr->getPendingAgentListUpdates(mSessionID));
142
143 if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
144 {
145 floaterp->requestAutoConnect();
146 LLFloaterIMPanel::onClickStartCall(floaterp);
147 // always open IM window when connecting to voice
148 LLFloaterChatterBox::showInstance(TRUE);
149 }
150 else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
151 {
152 LLFloaterChatterBox::showInstance(TRUE);
153 }
154 }
155
156 gIMMgr->clearPendingAgentListUpdates(mSessionID);
157 gIMMgr->clearPendingInvitation(mSessionID);
158 }
159 }
160
161 void error(U32 statusNum, const std::string& reason)
162 {
163 //throw something back to the viewer here?
164 if ( gIMMgr )
165 {
166 gIMMgr->clearPendingAgentListUpdates(mSessionID);
167 gIMMgr->clearPendingInvitation(mSessionID);
168
169 LLFloaterIMPanel* floaterp =
170 gIMMgr->findFloaterBySession(mSessionID);
171
172 if ( floaterp )
173 {
174 if ( 404 == statusNum )
175 {
176 std::string error_string;
177 error_string = "does not exist";
178
179 floaterp->showSessionStartError(
180 error_string);
181 }
182 }
183 }
184 }
185
186private:
187 LLUUID mSessionID;
188 LLIMMgr::EInvitationType mInvitiationType;
189};
190
100 191
101// the other_participant_id is either an agent_id, a group_id, or an inventory 192// the other_participant_id is either an agent_id, a group_id, or an inventory
102// folder item_id (collection of calling cards) 193// folder item_id (collection of calling cards)
@@ -256,41 +347,105 @@ protected:
256}; 347};
257 348
258 349
259class LLIMMgr::LLIMSessionInvite 350bool inviteUserResponse(const LLSD& notification, const LLSD& response)
260{ 351{
261public: 352 const LLSD& payload = notification["payload"];
262 LLIMSessionInvite( 353 LLUUID session_id = payload["session_id"].asUUID();
263 const LLUUID& session_id, 354 EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
264 const std::string& session_name, 355 LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
265 const LLUUID& caller_id, 356 S32 option = LLNotification::getSelectedOption(notification, response);
266 const std::string& caller_name, 357 switch(option)
267 EInstantMessage type, 358 {
268 EInvitationType inv_type, 359 case 0: // accept
269 const std::string& session_handle, 360 {
270 const std::string& notify_box, 361 if (type == IM_SESSION_P2P_INVITE)
271 const std::string& session_uri) : 362 {
272 mSessionID(session_id), 363 // create a normal IM session
273 mSessionName(session_name), 364 session_id = gIMMgr->addP2PSession(
274 mCallerID(caller_id), 365 payload["session_name"].asString(),
275 mCallerName(caller_name), 366 payload["caller_id"].asUUID(),
276 mType(type), 367 payload["session_handle"].asString(),
277 mInvType(inv_type), 368 payload["session_uri"].asString());
278 mSessionHandle(session_handle), 369
279 mNotifyBox(notify_box), 370 LLFloaterIMPanel* im_floater =
280 mSessionURI(session_uri) 371 gIMMgr->findFloaterBySession(
281 {}; 372 session_id);
282 373 if (im_floater)
283 LLUUID mSessionID; 374 {
284 std::string mSessionName; 375 im_floater->requestAutoConnect();
285 LLUUID mCallerID; 376 LLFloaterIMPanel::onClickStartCall(im_floater);
286 std::string mCallerName; 377 // always open IM window when connecting to voice
287 EInstantMessage mType; 378 LLFloaterChatterBox::showInstance(session_id);
288 EInvitationType mInvType; 379 }
289 std::string mSessionHandle; 380
290 std::string mNotifyBox; 381 gIMMgr->clearPendingAgentListUpdates(session_id);
291 std::string mSessionURI; 382 gIMMgr->clearPendingInvitation(session_id);
292}; 383 }
384 else
385 {
386 gIMMgr->addSession(
387 payload["session_name"].asString(),
388 type,
389 session_id);
390
391 std::string url = gAgent.getRegion()->getCapability(
392 "ChatSessionRequest");
393
394 LLSD data;
395 data["method"] = "accept invitation";
396 data["session-id"] = session_id;
397 LLHTTPClient::post(
398 url,
399 data,
400 new LLViewerChatterBoxInvitationAcceptResponder(
401 session_id,
402 inv_type));
403 }
404 }
405 break;
406 case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
407 {
408 // mute the sender of this invite
409 if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
410 {
411 LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
412 LLMuteList::getInstance()->add(mute);
413 }
414 }
415 /* FALLTHROUGH */
416
417 case 1: // decline
418 {
419 if (type == IM_SESSION_P2P_INVITE)
420 {
421 if(gVoiceClient)
422 {
423 std::string s = payload["session_handle"].asString();
424 gVoiceClient->declineInvite(s);
425 }
426 }
427 else
428 {
429 std::string url = gAgent.getRegion()->getCapability(
430 "ChatSessionRequest");
431
432 LLSD data;
433 data["method"] = "decline invitation";
434 data["session-id"] = session_id;
435 LLHTTPClient::post(
436 url,
437 data,
438 NULL);
439 }
440 }
293 441
442 gIMMgr->clearPendingAgentListUpdates(session_id);
443 gIMMgr->clearPendingInvitation(session_id);
444 break;
445 }
446
447 return false;
448}
294 449
295// 450//
296// Public Static Member Functions 451// Public Static Member Functions
@@ -515,7 +670,7 @@ void LLIMMgr::addMessage(
515 } 670 }
516} 671}
517 672
518void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args) 673void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
519{ 674{
520 LLUIString message; 675 LLUIString message;
521 676
@@ -525,7 +680,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
525 LLFloaterChat* floaterp = LLFloaterChat::getInstance(); 680 LLFloaterChat* floaterp = LLFloaterChat::getInstance();
526 681
527 message = floaterp->getString(message_name); 682 message = floaterp->getString(message_name);
528 message.setArgList(args); 683 message.setArgs(args);
529 684
530 LLChat chat(message); 685 LLChat chat(message);
531 chat.mSourceType = CHAT_SOURCE_SYSTEM; 686 chat.mSourceType = CHAT_SOURCE_SYSTEM;
@@ -537,7 +692,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
537 if (floaterp) 692 if (floaterp)
538 { 693 {
539 message = floaterp->getString(message_name); 694 message = floaterp->getString(message_name);
540 message.setArgList(args); 695 message.setArgs(args);
541 696
542 gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString()); 697 gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
543 } 698 }
@@ -699,7 +854,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
699 LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater); 854 LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
700 //mTabContainer->removeTabPanel(floater); 855 //mTabContainer->removeTabPanel(floater);
701 856
702 clearPendingInviation(session_id); 857 clearPendingInvitation(session_id);
703 clearPendingAgentListUpdates(session_id); 858 clearPendingAgentListUpdates(session_id);
704 } 859 }
705} 860}
@@ -746,22 +901,22 @@ void LLIMMgr::inviteToSession(
746 ad_hoc_invite = TRUE; 901 ad_hoc_invite = TRUE;
747 } 902 }
748 903
749 LLIMSessionInvite* invite = new LLIMSessionInvite( 904 LLSD payload;
750 session_id, 905 payload["session_id"] = session_id;
751 session_name, 906 payload["session_name"] = session_name;
752 caller_id, 907 payload["caller_id"] = caller_id;
753 caller_name, 908 payload["caller_name"] = caller_name;
754 type, 909 payload["type"] = type;
755 inv_type, 910 payload["inv_type"] = inv_type;
756 session_handle, 911 payload["session_handle"] = session_handle;
757 notify_box_type, 912 payload["session_uri"] = session_uri;
758 session_uri); 913 payload["notify_box_type"] = notify_box_type;
759 914
760 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id); 915 LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
761 if (channelp && channelp->callStarted()) 916 if (channelp && channelp->callStarted())
762 { 917 {
763 // you have already started a call to the other user, so just accept the invite 918 // you have already started a call to the other user, so just accept the invite
764 inviteUserResponse(0, invite); // inviteUserResponse deletes 919 LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
765 return; 920 return;
766 } 921 }
767 922
@@ -775,7 +930,7 @@ void LLIMMgr::inviteToSession(
775 if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly")) 930 if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
776 { 931 {
777 // invite not from a friend, so decline 932 // invite not from a friend, so decline
778 inviteUserResponse(1, invite); // inviteUserResponse deletes 933 LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
779 return; 934 return;
780 } 935 }
781 } 936 }
@@ -785,231 +940,41 @@ void LLIMMgr::inviteToSession(
785 { 940 {
786 if (caller_name.empty()) 941 if (caller_name.empty())
787 { 942 {
788 gCacheName->get(caller_id, FALSE, onInviteNameLookup, invite); 943 gCacheName->getName(caller_id, onInviteNameLookup, new LLSD(payload));
789 } 944 }
790 else 945 else
791 { 946 {
792 LLStringUtil::format_map_t args; 947 LLSD args;
793 args["[NAME]"] = caller_name; 948 args["NAME"] = caller_name;
794 args["[GROUP]"] = session_name; 949 args["GROUP"] = session_name;
795 950
796 LLNotifyBox::showXml(notify_box_type, 951 LLNotifications::instance().add(notify_box_type,
797 args, 952 args,
798 inviteUserResponse, 953 payload,
799 (void*)invite); // inviteUserResponse deletes 954 &inviteUserResponse);
800 955
801 } 956 }
802 mPendingInvitations[session_id.asString()] = LLSD(); 957 mPendingInvitations[session_id.asString()] = LLSD();
803 } 958 }
804 else
805 {
806 delete invite;
807 }
808} 959}
809 960
810//static 961//static
811void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata) 962void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
812{ 963{
813 LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata; 964 LLSD payload = *(LLSD*)userdata;
965 delete (LLSD*)userdata;
814 966
815 invite->mCallerName = first + " " + last; 967 payload["caller_name"] = first + " " + last;
816 invite->mSessionName = invite->mCallerName; 968 payload["session_name"] = payload["caller_name"].asString();
817 969
818 LLStringUtil::format_map_t args; 970 LLSD args;
819 args["[NAME]"] = invite->mCallerName; 971 args["NAME"] = payload["caller_name"].asString();
820 972
821 LLNotifyBox::showXml( 973 LLNotifications::instance().add(
822 invite->mNotifyBox, 974 payload["notify_box_type"].asString(),
823 args, 975 args,
824 inviteUserResponse, 976 payload,
825 (void*)invite); 977 &inviteUserResponse);
826}
827
828class LLViewerChatterBoxInvitationAcceptResponder :
829 public LLHTTPClient::Responder
830{
831public:
832 LLViewerChatterBoxInvitationAcceptResponder(
833 const LLUUID& session_id,
834 LLIMMgr::EInvitationType invitation_type)
835 {
836 mSessionID = session_id;
837 mInvitiationType = invitation_type;
838 }
839
840 void result(const LLSD& content)
841 {
842 if ( gIMMgr)
843 {
844 LLFloaterIMPanel* floaterp =
845 gIMMgr->findFloaterBySession(mSessionID);
846
847 if (floaterp)
848 {
849 //we've accepted our invitation
850 //and received a list of agents that were
851 //currently in the session when the reply was sent
852 //to us. Now, it is possible that there were some agents
853 //to slip in/out between when that message was sent to us
854 //and now.
855
856 //the agent list updates we've received have been
857 //accurate from the time we were added to the session
858 //but unfortunately, our base that we are receiving here
859 //may not be the most up to date. It was accurate at
860 //some point in time though.
861 floaterp->setSpeakers(content);
862
863 //we now have our base of users in the session
864 //that was accurate at some point, but maybe not now
865 //so now we apply all of the udpates we've received
866 //in case of race conditions
867 floaterp->updateSpeakersList(
868 gIMMgr->getPendingAgentListUpdates(mSessionID));
869
870 if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
871 {
872 floaterp->requestAutoConnect();
873 LLFloaterIMPanel::onClickStartCall(floaterp);
874 // always open IM window when connecting to voice
875 LLFloaterChatterBox::showInstance(TRUE);
876 }
877 else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
878 {
879 LLFloaterChatterBox::showInstance(TRUE);
880 }
881 }
882
883 gIMMgr->clearPendingAgentListUpdates(mSessionID);
884 gIMMgr->clearPendingInviation(mSessionID);
885 }
886 }
887
888 void error(U32 statusNum, const std::string& reason)
889 {
890 //throw something back to the viewer here?
891 if ( gIMMgr )
892 {
893 gIMMgr->clearPendingAgentListUpdates(mSessionID);
894 gIMMgr->clearPendingInviation(mSessionID);
895
896 LLFloaterIMPanel* floaterp =
897 gIMMgr->findFloaterBySession(mSessionID);
898
899 if ( floaterp )
900 {
901 if ( 404 == statusNum )
902 {
903 std::string error_string;
904 error_string = "does not exist";
905
906 floaterp->showSessionStartError(
907 error_string);
908 }
909 }
910 }
911 }
912
913private:
914 LLUUID mSessionID;
915 LLIMMgr::EInvitationType mInvitiationType;
916};
917
918//static
919void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
920{
921 LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
922
923 switch(option)
924 {
925 case 0: // accept
926 {
927 if (invitep->mType == IM_SESSION_P2P_INVITE)
928 {
929 // create a normal IM session
930 invitep->mSessionID = gIMMgr->addP2PSession(
931 invitep->mSessionName,
932 invitep->mCallerID,
933 invitep->mSessionHandle,
934 invitep->mSessionURI );
935
936 LLFloaterIMPanel* im_floater =
937 gIMMgr->findFloaterBySession(
938 invitep->mSessionID);
939 if (im_floater)
940 {
941 im_floater->requestAutoConnect();
942 LLFloaterIMPanel::onClickStartCall(im_floater);
943 // always open IM window when connecting to voice
944 LLFloaterChatterBox::showInstance(invitep->mSessionID);
945 }
946
947 gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
948 gIMMgr->clearPendingInviation(invitep->mSessionID);
949 }
950 else
951 {
952 gIMMgr->addSession(
953 invitep->mSessionName,
954 invitep->mType,
955 invitep->mSessionID);
956
957 std::string url = gAgent.getRegion()->getCapability(
958 "ChatSessionRequest");
959
960 LLSD data;
961 data["method"] = "accept invitation";
962 data["session-id"] = invitep->mSessionID;
963 LLHTTPClient::post(
964 url,
965 data,
966 new LLViewerChatterBoxInvitationAcceptResponder(
967 invitep->mSessionID,
968 invitep->mInvType));
969 }
970 }
971 break;
972 case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
973 {
974 // mute the sender of this invite
975 if (!LLMuteList::getInstance()->isMuted(invitep->mCallerID))
976 {
977 LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
978 LLMuteList::getInstance()->add(mute);
979 }
980 }
981 /* FALLTHROUGH */
982
983 case 1: // decline
984 {
985 if (invitep->mType == IM_SESSION_P2P_INVITE)
986 {
987 if(gVoiceClient)
988 {
989 gVoiceClient->declineInvite(invitep->mSessionHandle);
990 }
991 }
992 else
993 {
994 std::string url = gAgent.getRegion()->getCapability(
995 "ChatSessionRequest");
996
997 LLSD data;
998 data["method"] = "decline invitation";
999 data["session-id"] = invitep->mSessionID;
1000 LLHTTPClient::post(
1001 url,
1002 data,
1003 NULL);
1004 }
1005 }
1006
1007 gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
1008 gIMMgr->clearPendingInviation(invitep->mSessionID);
1009 break;
1010 }
1011
1012 delete invitep;
1013} 978}
1014 979
1015void LLIMMgr::refresh() 980void LLIMMgr::refresh()
@@ -1083,7 +1048,7 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id)
1083 return (findFloaterBySession(session_id) != NULL); 1048 return (findFloaterBySession(session_id) != NULL);
1084} 1049}
1085 1050
1086void LLIMMgr::clearPendingInviation(const LLUUID& session_id) 1051void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
1087{ 1052{
1088 if ( mPendingInvitations.has(session_id.asString()) ) 1053 if ( mPendingInvitations.has(session_id.asString()) )
1089 { 1054 {