aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llviewermessage.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llviewermessage.cpp1400
1 files changed, 832 insertions, 568 deletions
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 461a598..de1d6dd 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -18,7 +18,8 @@
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 21 * online at
22 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 23 *
23 * By copying, modifying or distributing this software, you acknowledge 24 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 25 * that you have read and understood your obligations described above,
@@ -72,6 +73,7 @@
72#include "lldrawpool.h" 73#include "lldrawpool.h"
73#include "llfirstuse.h" 74#include "llfirstuse.h"
74#include "llfloateractivespeakers.h" 75#include "llfloateractivespeakers.h"
76#include "llfloateranimpreview.h"
75#include "llfloaterbuycurrency.h" 77#include "llfloaterbuycurrency.h"
76#include "llfloaterbuyland.h" 78#include "llfloaterbuyland.h"
77#include "llfloaterchat.h" 79#include "llfloaterchat.h"
@@ -80,7 +82,6 @@
80#include "llfloaterland.h" 82#include "llfloaterland.h"
81#include "llfloaterregioninfo.h" 83#include "llfloaterregioninfo.h"
82#include "llfloaterlandholdings.h" 84#include "llfloaterlandholdings.h"
83#include "llfloatermap.h"
84#include "llurldispatcher.h" 85#include "llurldispatcher.h"
85#include "llfloatermute.h" 86#include "llfloatermute.h"
86#include "llfloaterpostcard.h" 87#include "llfloaterpostcard.h"
@@ -95,7 +96,7 @@
95#include "llinventoryview.h" 96#include "llinventoryview.h"
96#include "llmenugl.h" 97#include "llmenugl.h"
97#include "llmutelist.h" 98#include "llmutelist.h"
98#include "llnetmap.h" 99#include "llnotifications.h"
99#include "llnotify.h" 100#include "llnotify.h"
100#include "llpanelgrouplandmoney.h" 101#include "llpanelgrouplandmoney.h"
101#include "llselectmgr.h" 102#include "llselectmgr.h"
@@ -131,7 +132,6 @@
131#include "pipeline.h" 132#include "pipeline.h"
132#include "llappviewer.h" 133#include "llappviewer.h"
133#include "llfloaterworldmap.h" 134#include "llfloaterworldmap.h"
134#include "llkeythrottle.h"
135#include "llviewerdisplay.h" 135#include "llviewerdisplay.h"
136#include "llkeythrottle.h" 136#include "llkeythrottle.h"
137 137
@@ -157,7 +157,6 @@ extern BOOL gDebugClicks;
157 157
158// function prototypes 158// function prototypes
159void open_offer(const std::vector<LLUUID>& items, const std::string& from_name); 159void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
160void friendship_offer_callback(S32 option, void* user_data);
161bool check_offer_throttle(const std::string& from_name, bool check_only); 160bool check_offer_throttle(const std::string& from_name, bool check_only);
162void callbackCacheEstateOwnerName(const LLUUID& id, 161void callbackCacheEstateOwnerName(const LLUUID& id,
163 const std::string& first, const std::string& last, 162 const std::string& first, const std::string& last,
@@ -184,14 +183,68 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] =
184 "ControlYourCamera" 183 "ControlYourCamera"
185 }; 184 };
186 185
187struct LLFriendshipOffer 186const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
188{ 187{
189 LLUUID mFromID; 188 TRUE, // ScriptTakeMoney,
190 LLUUID mTransactionID; 189 FALSE, // ActOnControlInputs
191 BOOL mOnline; 190 FALSE, // RemapControlInputs
192 LLHost mHost; 191 FALSE, // AnimateYourAvatar
192 FALSE, // AttachToYourAvatar
193 FALSE, // ReleaseOwnership,
194 FALSE, // LinkAndDelink,
195 FALSE, // AddAndRemoveJoints
196 FALSE, // ChangePermissions
197 FALSE, // TrackYourCamera,
198 FALSE // ControlYourCamera
193}; 199};
194 200
201bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
202{
203 S32 option = LLNotification::getSelectedOption(notification, response);
204 LLUUID fid;
205 LLMessageSystem* msg = gMessageSystem;
206 const LLSD& payload = notification["payload"];
207 switch(option)
208 {
209 case 0:
210 // accept
211 LLAvatarTracker::formFriendship(payload["from_id"]);
212
213 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
214
215 // This will also trigger an onlinenotification if the user is online
216 msg->newMessageFast(_PREHASH_AcceptFriendship);
217 msg->nextBlockFast(_PREHASH_AgentData);
218 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
219 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
220 msg->nextBlockFast(_PREHASH_TransactionBlock);
221 msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
222 msg->nextBlockFast(_PREHASH_FolderData);
223 msg->addUUIDFast(_PREHASH_FolderID, fid);
224 msg->sendReliable(LLHost(payload["sender"].asString()));
225 break;
226 case 1:
227 // decline
228 // We no longer notify other viewers, but we DO still send
229 // the rejection to the simulator to delete the pending userop.
230 msg->newMessageFast(_PREHASH_DeclineFriendship);
231 msg->nextBlockFast(_PREHASH_AgentData);
232 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
233 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
234 msg->nextBlockFast(_PREHASH_TransactionBlock);
235 msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
236 msg->sendReliable(LLHost(payload["sender"].asString()));
237 break;
238 default:
239 // close button probably, possibly timed out
240 break;
241 }
242
243 return false;
244}
245static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
246static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
247
195//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have " 248//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have "
196// "requested not to be disturbed. Your message will still be shown in their IM " 249// "requested not to be disturbed. Your message will still be shown in their IM "
197// "panel for later viewing."; 250// "panel for later viewing.";
@@ -563,34 +616,31 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
563 gAgent.sendMessage(); 616 gAgent.sendMessage();
564} 617}
565 618
566struct LLJoinGroupData 619bool join_group_response(const LLSD& notification, const LLSD& response)
567{
568 LLUUID mGroupID;
569 LLUUID mTransactionID;
570 std::string mName;
571 std::string mMessage;
572 S32 mFee;
573};
574
575void join_group_callback(S32 option, void* user_data)
576{ 620{
577 LLJoinGroupData* data = (LLJoinGroupData*)user_data; 621 S32 option = LLNotification::getSelectedOption(notification, response);
578 BOOL delete_context_data = TRUE; 622 BOOL delete_context_data = TRUE;
579 bool accept_invite = false; 623 bool accept_invite = false;
580 624
581 if (option == 2 && data && !data->mGroupID.isNull()) 625 LLUUID group_id = notification["payload"]["group_id"].asUUID();
626 LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
627 std::string name = notification["payload"]["name"].asString();
628 std::string message = notification["payload"]["message"].asString();
629 S32 fee = notification["payload"]["fee"].asInteger();
630
631 if (option == 2 && !group_id.isNull())
582 { 632 {
583 LLFloaterGroupInfo::showFromUUID(data->mGroupID); 633 LLFloaterGroupInfo::showFromUUID(group_id);
584 LLStringUtil::format_map_t args; 634 LLSD args;
585 args["[MESSAGE]"] = data->mMessage; 635 args["MESSAGE"] = message;
586 LLNotifyBox::showXml("JoinGroup", args, &join_group_callback, data); 636 LLNotifications::instance().add("JoinGroup", args, notification["payload"]);
587 return; 637 return false;
588 } 638 }
589 if(option == 0 && data && !data->mGroupID.isNull()) 639 if(option == 0 && !group_id.isNull())
590 { 640 {
591 // check for promotion or demotion. 641 // check for promotion or demotion.
592 S32 max_groups = MAX_AGENT_GROUPS; 642 S32 max_groups = MAX_AGENT_GROUPS;
593 if(gAgent.isInGroup(data->mGroupID)) ++max_groups; 643 if(gAgent.isInGroup(group_id)) ++max_groups;
594 644
595 if(gAgent.mGroups.count() < max_groups) 645 if(gAgent.mGroups.count() < max_groups)
596 { 646 {
@@ -599,10 +649,10 @@ void join_group_callback(S32 option, void* user_data)
599 else 649 else
600 { 650 {
601 delete_context_data = FALSE; 651 delete_context_data = FALSE;
602 LLStringUtil::format_map_t args; 652 LLSD args;
603 args["[NAME]"] = data->mName; 653 args["NAME"] = name;
604 args["[INVITE]"] = data->mMessage; 654 args["INVITE"] = message;
605 LLAlertDialog::showXml("JoinedTooManyGroupsMember", args, join_group_callback, (void*)data); 655 LLNotifications::instance().add("JoinedTooManyGroupsMember", args, notification["payload"]);
606 } 656 }
607 } 657 }
608 658
@@ -610,45 +660,44 @@ void join_group_callback(S32 option, void* user_data)
610 { 660 {
611 // If there is a fee to join this group, make 661 // If there is a fee to join this group, make
612 // sure the user is sure they want to join. 662 // sure the user is sure they want to join.
613 if (data->mFee > 0) 663 if (fee > 0)
614 { 664 {
615 delete_context_data = FALSE; 665 delete_context_data = FALSE;
616 LLStringUtil::format_map_t args; 666 LLSD args;
617 args["[COST]"] = llformat("%d", data->mFee); 667 args["COST"] = llformat("%d", fee);
618 // Set the fee to 0, so that we don't keep 668 // Set the fee for next time to 0, so that we don't keep
619 // asking about a fee. 669 // asking about a fee.
620 data->mFee = 0; 670 LLSD next_payload = notification["payload"];
621 gViewerWindow->alertXml("JoinGroupCanAfford", 671 next_payload["fee"] = 0;
672 LLNotifications::instance().add("JoinGroupCanAfford",
622 args, 673 args,
623 join_group_callback, 674 next_payload);
624 (void*)data);
625 } 675 }
626 else 676 else
627 { 677 {
628 send_improved_im(data->mGroupID, 678 send_improved_im(group_id,
629 std::string("name"), 679 std::string("name"),
630 std::string("message"), 680 std::string("message"),
631 IM_ONLINE, 681 IM_ONLINE,
632 IM_GROUP_INVITATION_ACCEPT, 682 IM_GROUP_INVITATION_ACCEPT,
633 data->mTransactionID); 683 transaction_id);
634 } 684 }
635 } 685 }
636 else if (data) 686 else
637 { 687 {
638 send_improved_im(data->mGroupID, 688 send_improved_im(group_id,
639 std::string("name"), 689 std::string("name"),
640 std::string("message"), 690 std::string("message"),
641 IM_ONLINE, 691 IM_ONLINE,
642 IM_GROUP_INVITATION_DECLINE, 692 IM_GROUP_INVITATION_DECLINE,
643 data->mTransactionID); 693 transaction_id);
644 } 694 }
645 695
646 if(delete_context_data) 696 return false;
647 {
648 delete data;
649 data = NULL;
650 }
651} 697}
698static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
699static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
700static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
652 701
653 702
654//----------------------------------------------------------------------------- 703//-----------------------------------------------------------------------------
@@ -672,7 +721,7 @@ private:
672//instance of the AddedObserver for TaskOffers 721//instance of the AddedObserver for TaskOffers
673//and it never dies. We do this because we don't know the UUID of 722//and it never dies. We do this because we don't know the UUID of
674//task offers until they are accepted, so we don't wouldn't 723//task offers until they are accepted, so we don't wouldn't
675//know what to watch for, so instead we just watch for all additions. -Gigs 724//know what to watch for, so instead we just watch for all additions.
676class LLOpenTaskOffer : public LLInventoryAddedObserver 725class LLOpenTaskOffer : public LLInventoryAddedObserver
677{ 726{
678protected: 727protected:
@@ -748,7 +797,7 @@ protected:
748 797
749//Returns TRUE if we are OK, FALSE if we are throttled 798//Returns TRUE if we are OK, FALSE if we are throttled
750//Set check_only true if you want to know the throttle status 799//Set check_only true if you want to know the throttle status
751//without registering a hit -Gigs 800//without registering a hit
752bool check_offer_throttle(const std::string& from_name, bool check_only) 801bool check_offer_throttle(const std::string& from_name, bool check_only)
753{ 802{
754 static U32 throttle_count; 803 static U32 throttle_count;
@@ -775,14 +824,14 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
775 { 824 {
776 LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL; 825 LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL;
777 // When downloading the initial inventory we get a lot of new items 826 // When downloading the initial inventory we get a lot of new items
778 // coming in and can't tell that from spam. JC 827 // coming in and can't tell that from spam.
779 if (LLStartUp::getStartupState() >= STATE_STARTED 828 if (LLStartUp::getStartupState() >= STATE_STARTED
780 && throttle_count >= OFFER_THROTTLE_MAX_COUNT) 829 && throttle_count >= OFFER_THROTTLE_MAX_COUNT)
781 { 830 {
782 if (!throttle_logged) 831 if (!throttle_logged)
783 { 832 {
784 // Use the name of the last item giver, who is probably the person 833 // Use the name of the last item giver, who is probably the person
785 // spamming you. JC 834 // spamming you.
786 std::ostringstream message; 835 std::ostringstream message;
787 message << LLAppViewer::instance()->getSecondLifeTitle(); 836 message << LLAppViewer::instance()->getSecondLifeTitle();
788 if (!from_name.empty()) 837 if (!from_name.empty())
@@ -830,10 +879,10 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
830 } 879 }
831 LLAssetType::EType asset_type = item->getType(); 880 LLAssetType::EType asset_type = item->getType();
832 881
833 //if we are throttled, don't display them - Gigs 882 //if we are throttled, don't display them
834 if (check_offer_throttle(from_name, false)) 883 if (check_offer_throttle(from_name, false))
835 { 884 {
836 // I'm not sure this is a good idea. JC 885 // I'm not sure this is a good idea.
837 bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID(); 886 bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
838 //bool show_keep_discard = true; 887 //bool show_keep_discard = true;
839 switch(asset_type) 888 switch(asset_type)
@@ -885,7 +934,7 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
885 return; 934 return;
886 } 935 }
887 936
888 //Not sure about this check. Could make it easy to miss incoming items. -Gigs 937 //Not sure about this check. Could make it easy to miss incoming items.
889 //don't dick with highlight while the user is working 938 //don't dick with highlight while the user is working
890 //if(inventory_has_focus && !user_is_away) 939 //if(inventory_has_focus && !user_is_away)
891 // break; 940 // break;
@@ -930,9 +979,15 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
930 { 979 {
931 public: 980 public:
932 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} 981 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
933 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const 982 BOOL matches(const LLNotificationPtr notification) const
934 { 983 {
935 return callback == inventory_offer_callback && ((LLOfferInfo*)cb_data)->mFromID == blocked_id; 984 if(notification->getName() == "ObjectGiveItem"
985 || notification->getName() == "ObjectGiveItemUnknownUser"
986 || notification->getName() == "UserGiveItem")
987 {
988 return (notification->getPayload()["from_id"].asUUID() == blocked_id);
989 }
990 return FALSE;
936 } 991 }
937 private: 992 private:
938 const LLUUID& blocked_id; 993 const LLUUID& blocked_id;
@@ -940,21 +995,52 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
940 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id)); 995 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id));
941} 996}
942 997
943void inventory_offer_callback(S32 button, void* user_data) 998LLOfferInfo::LLOfferInfo(const LLSD& sd)
999{
1000 mIM = (EInstantMessage)sd["im_type"].asInteger();
1001 mFromID = sd["from_id"].asUUID();
1002 mFromGroup = sd["from_group"].asBoolean();
1003 mFromObject = sd["from_object"].asBoolean();
1004 mTransactionID = sd["transaction_id"].asUUID();
1005 mFolderID = sd["folder_id"].asUUID();
1006 mObjectID = sd["object_id"].asUUID();
1007 mType = LLAssetType::lookup(sd["type"].asString().c_str());
1008 mFromName = sd["from_name"].asString();
1009 mDesc = sd["description"].asString();
1010 mHost = LLHost(sd["sender"].asString());
1011}
1012
1013LLSD LLOfferInfo::asLLSD()
1014{
1015 LLSD sd;
1016 sd["im_type"] = mIM;
1017 sd["from_id"] = mFromID;
1018 sd["from_group"] = mFromGroup;
1019 sd["from_object"] = mFromObject;
1020 sd["transaction_id"] = mTransactionID;
1021 sd["folder_id"] = mFolderID;
1022 sd["object_id"] = mObjectID;
1023 sd["type"] = LLAssetType::lookup(mType);
1024 sd["from_name"] = mFromName;
1025 sd["description"] = mDesc;
1026 sd["sender"] = mHost.getIPandPort();
1027 return sd;
1028}
1029
1030bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
944 { 1031 {
945 LLChat chat; 1032 LLChat chat;
946 std::string log_message; 1033 std::string log_message;
947 LLOfferInfo* info = (LLOfferInfo*)user_data; 1034 S32 button = LLNotification::getSelectedOption(notification, response);
948 if(!info) return;
949 1035
950 // For muting, we need to add the mute, then decline the offer. 1036 // For muting, we need to add the mute, then decline the offer.
951 // This must be done here because: 1037 // This must be done here because:
952 // * callback may be called immediately, 1038 // * callback may be called immediately,
953 // * adding the mute sends a message, 1039 // * adding the mute sends a message,
954 // * we can't build two messages at once. JC 1040 // * we can't build two messages at once.
955 if (2 == button) 1041 if (2 == button)
956 { 1042 {
957 gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data); 1043 gCacheName->get(mFromID, mFromGroup, inventory_offer_mute_callback, this);
958 } 1044 }
959 1045
960 LLMessageSystem* msg = gMessageSystem; 1046 LLMessageSystem* msg = gMessageSystem;
@@ -964,9 +1050,9 @@ void inventory_offer_callback(S32 button, void* user_data)
964 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 1050 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
965 msg->nextBlockFast(_PREHASH_MessageBlock); 1051 msg->nextBlockFast(_PREHASH_MessageBlock);
966 msg->addBOOLFast(_PREHASH_FromGroup, FALSE); 1052 msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
967 msg->addUUIDFast(_PREHASH_ToAgentID, info->mFromID); 1053 msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
968 msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); 1054 msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
969 msg->addUUIDFast(_PREHASH_ID, info->mTransactionID); 1055 msg->addUUIDFast(_PREHASH_ID, mTransactionID);
970 msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary 1056 msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
971 std::string name; 1057 std::string name;
972 gAgent.buildFullname(name); 1058 gAgent.buildFullname(name);
@@ -977,50 +1063,50 @@ void inventory_offer_callback(S32 button, void* user_data)
977 msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); 1063 msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
978 LLInventoryObserver* opener = NULL; 1064 LLInventoryObserver* opener = NULL;
979 LLViewerInventoryCategory* catp = NULL; 1065 LLViewerInventoryCategory* catp = NULL;
980 catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID); 1066 catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
981 LLViewerInventoryItem* itemp = NULL; 1067 LLViewerInventoryItem* itemp = NULL;
982 if(!catp) 1068 if(!catp)
983 { 1069 {
984 itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID); 1070 itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
985 } 1071 }
986 1072
987 // *TODO:translate 1073 // *TODO:translate
988 std::string from_string; // Used in the pop-up. 1074 std::string from_string; // Used in the pop-up.
989 std::string chatHistory_string; // Used in chat history. 1075 std::string chatHistory_string; // Used in chat history.
990 if (info->mFromObject == TRUE) 1076 if (mFromObject == TRUE)
991 { 1077 {
992 if (info->mFromGroup) 1078 if (mFromGroup)
993 { 1079 {
994 std::string group_name; 1080 std::string group_name;
995 if (gCacheName->getGroupName(info->mFromID, group_name)) 1081 if (gCacheName->getGroupName(mFromID, group_name))
996 { 1082 {
997 from_string = std::string("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; 1083 from_string = std::string("An object named '") + mFromName + "' owned by the group '" + group_name + "'";
998 chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'"; 1084 chatHistory_string = mFromName + " owned by the group '" + group_name + "'";
999 } 1085 }
1000 else 1086 else
1001 { 1087 {
1002 from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown group"; 1088 from_string = std::string("An object named '") + mFromName + "' owned by an unknown group";
1003 chatHistory_string = info->mFromName + " owned by an unknown group"; 1089 chatHistory_string = mFromName + " owned by an unknown group";
1004 } 1090 }
1005 } 1091 }
1006 else 1092 else
1007 { 1093 {
1008 std::string first_name, last_name; 1094 std::string first_name, last_name;
1009 if (gCacheName->getName(info->mFromID, first_name, last_name)) 1095 if (gCacheName->getName(mFromID, first_name, last_name))
1010 { 1096 {
1011 from_string = std::string("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; 1097 from_string = std::string("An object named '") + mFromName + "' owned by " + first_name + " " + last_name;
1012 chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name; 1098 chatHistory_string = mFromName + " owned by " + first_name + " " + last_name;
1013 } 1099 }
1014 else 1100 else
1015 { 1101 {
1016 from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown user"; 1102 from_string = std::string("An object named '") + mFromName + "' owned by an unknown user";
1017 chatHistory_string = info->mFromName + " owned by an unknown user"; 1103 chatHistory_string = mFromName + " owned by an unknown user";
1018 } 1104 }
1019 } 1105 }
1020 } 1106 }
1021 else 1107 else
1022 { 1108 {
1023 from_string = chatHistory_string = info->mFromName; 1109 from_string = chatHistory_string = mFromName;
1024 } 1110 }
1025 1111
1026 bool busy=FALSE; 1112 bool busy=FALSE;
@@ -1033,24 +1119,24 @@ void inventory_offer_callback(S32 button, void* user_data)
1033 // group_notice_inventory is 1 greater than the offer integer value. 1119 // group_notice_inventory is 1 greater than the offer integer value.
1034 // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 1120 // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
1035 // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED 1121 // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
1036 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 1)); 1122 msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
1037 msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(info->mFolderID.mData), 1123 msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
1038 sizeof(info->mFolderID.mData)); 1124 sizeof(mFolderID.mData));
1039 // send the message 1125 // send the message
1040 msg->sendReliable(info->mHost); 1126 msg->sendReliable(mHost);
1041 1127
1042 //don't spam them if they are getting flooded 1128 //don't spam them if they are getting flooded
1043 if (check_offer_throttle(info->mFromName, true)) 1129 if (check_offer_throttle(mFromName, true))
1044 { 1130 {
1045 log_message = chatHistory_string + " gave you " + info->mDesc + "."; 1131 log_message = chatHistory_string + " gave you " + mDesc + ".";
1046 chat.mText = log_message; 1132 chat.mText = log_message;
1047 LLFloaterChat::addChatHistory(chat); 1133 LLFloaterChat::addChatHistory(chat);
1048 } 1134 }
1049 1135
1050 // we will want to open this item when it comes back. 1136 // we will want to open this item when it comes back.
1051 LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << info->mTransactionID 1137 LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
1052 << LL_ENDL; 1138 << LL_ENDL;
1053 switch (info->mIM) 1139 switch (mIM)
1054 { 1140 {
1055 case IM_INVENTORY_OFFERED: 1141 case IM_INVENTORY_OFFERED:
1056 { 1142 {
@@ -1058,7 +1144,7 @@ void inventory_offer_callback(S32 button, void* user_data)
1058 // end has already copied the items into your inventory, 1144 // end has already copied the items into your inventory,
1059 // so we can fetch it out of our inventory. 1145 // so we can fetch it out of our inventory.
1060 LLInventoryFetchObserver::item_ref_t items; 1146 LLInventoryFetchObserver::item_ref_t items;
1061 items.push_back(info->mObjectID); 1147 items.push_back(mObjectID);
1062 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string); 1148 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
1063 open_agent_offer->fetchItems(items); 1149 open_agent_offer->fetchItems(items);
1064 if(catp || (itemp && itemp->isComplete())) 1150 if(catp || (itemp && itemp->isComplete()))
@@ -1084,7 +1170,7 @@ void inventory_offer_callback(S32 button, void* user_data)
1084 default: 1170 default:
1085 LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL; 1171 LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
1086 break; 1172 break;
1087 } // end switch (info->mIM) 1173 } // end switch (mIM)
1088 break; 1174 break;
1089 1175
1090 case IOR_BUSY: 1176 case IOR_BUSY:
@@ -1100,14 +1186,14 @@ void inventory_offer_callback(S32 button, void* user_data)
1100 // or IM_GROUP_NOTICE_INVENTORY_DECLINED 1186 // or IM_GROUP_NOTICE_INVENTORY_DECLINED
1101 default: 1187 default:
1102 // close button probably (or any of the fall-throughs from above) 1188 // close button probably (or any of the fall-throughs from above)
1103 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2)); 1189 msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
1104 msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE); 1190 msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
1105 // send the message 1191 // send the message
1106 msg->sendReliable(info->mHost); 1192 msg->sendReliable(mHost);
1107 1193
1108 log_message = "You decline " + info->mDesc + " from " + info->mFromName + "."; 1194 log_message = "You decline " + mDesc + " from " + mFromName + ".";
1109 chat.mText = log_message; 1195 chat.mText = log_message;
1110 if( LLMuteList::getInstance()->isMuted(info->mFromID ) && ! LLMuteList::getInstance()->isLinden(info->mFromName) ) // muting for SL-42269 1196 if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
1111 { 1197 {
1112 chat.mMuted = TRUE; 1198 chat.mMuted = TRUE;
1113 } 1199 }
@@ -1116,13 +1202,13 @@ void inventory_offer_callback(S32 button, void* user_data)
1116 // If it's from an agent, we have to fetch the item to throw 1202 // If it's from an agent, we have to fetch the item to throw
1117 // it away. If it's from a task or group, just denying the 1203 // it away. If it's from a task or group, just denying the
1118 // request will suffice to discard the item. 1204 // request will suffice to discard the item.
1119 if(IM_INVENTORY_OFFERED == info->mIM) 1205 if(IM_INVENTORY_OFFERED == mIM)
1120 { 1206 {
1121 LLInventoryFetchComboObserver::folder_ref_t folders; 1207 LLInventoryFetchComboObserver::folder_ref_t folders;
1122 LLInventoryFetchComboObserver::item_ref_t items; 1208 LLInventoryFetchComboObserver::item_ref_t items;
1123 items.push_back(info->mObjectID); 1209 items.push_back(mObjectID);
1124 LLDiscardAgentOffer* discard_agent_offer; 1210 LLDiscardAgentOffer* discard_agent_offer;
1125 discard_agent_offer = new LLDiscardAgentOffer(info->mFolderID, info->mObjectID); 1211 discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
1126 discard_agent_offer->fetch(folders, items); 1212 discard_agent_offer->fetch(folders, items);
1127 if(catp || (itemp && itemp->isComplete())) 1213 if(catp || (itemp && itemp->isComplete()))
1128 { 1214 {
@@ -1134,9 +1220,9 @@ void inventory_offer_callback(S32 button, void* user_data)
1134 } 1220 }
1135 1221
1136 } 1222 }
1137 if (busy && (!info->mFromGroup && !info->mFromObject)) 1223 if (busy && (!mFromGroup && !mFromObject))
1138 { 1224 {
1139 busy_message(msg,info->mFromID); 1225 busy_message(msg,mFromID);
1140 } 1226 }
1141 break; 1227 break;
1142 } 1228 }
@@ -1146,12 +1232,12 @@ void inventory_offer_callback(S32 button, void* user_data)
1146 gInventory.addObserver(opener); 1232 gInventory.addObserver(opener);
1147 } 1233 }
1148 1234
1149 delete info;
1150 info = NULL;
1151
1152 // Allow these to stack up, but once you deal with one, reset the 1235 // Allow these to stack up, but once you deal with one, reset the
1153 // position. 1236 // position.
1154 gFloaterView->resetStartingFloaterPosition(); 1237 gFloaterView->resetStartingFloaterPosition();
1238
1239 delete this;
1240 return false;
1155} 1241}
1156 1242
1157 1243
@@ -1161,14 +1247,14 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1161 //accepting it. SEE SL-39554 1247 //accepting it. SEE SL-39554
1162 if (gAgent.getBusy()) 1248 if (gAgent.getBusy())
1163 { 1249 {
1164 inventory_offer_callback(IOR_BUSY, info); 1250 info->forceResponse(IOR_BUSY);
1165 return; 1251 return;
1166 } 1252 }
1167 1253
1168 //If muted, don't even go through the messaging stuff. Just curtail the offer here. 1254 //If muted, don't even go through the messaging stuff. Just curtail the offer here.
1169 if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName)) 1255 if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
1170 { 1256 {
1171 inventory_offer_callback(IOR_MUTE, info); 1257 info->forceResponse(IOR_MUTE);
1172 return; 1258 return;
1173 } 1259 }
1174 1260
@@ -1180,7 +1266,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1180 { 1266 {
1181 // For certain types, just accept the items into the inventory, 1267 // For certain types, just accept the items into the inventory,
1182 // and possibly open them on receipt depending upon "ShowNewInventory". 1268 // and possibly open them on receipt depending upon "ShowNewInventory".
1183 inventory_offer_callback(IOR_ACCEPT, info); 1269 info->forceResponse(IOR_ACCEPT);
1184 return; 1270 return;
1185 } 1271 }
1186 1272
@@ -1192,36 +1278,38 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1192 LLStringUtil::truncate(msg, indx); 1278 LLStringUtil::truncate(msg, indx);
1193 } 1279 }
1194 1280
1195 LLStringUtil::format_map_t args; 1281 LLSD args;
1196 args["[OBJECTNAME]"] = msg; 1282 args["[OBJECTNAME]"] = msg;
1197 1283
1284 LLSD payload;
1285
1198 // must protect against a NULL return from lookupHumanReadable() 1286 // must protect against a NULL return from lookupHumanReadable()
1199 std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType)); 1287 std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
1200 if (!typestr.empty()) 1288 if (!typestr.empty())
1201 { 1289 {
1202 args["[OBJECTTYPE]"] = typestr; 1290 args["OBJECTTYPE"] = typestr;
1203 } 1291 }
1204 else 1292 else
1205 { 1293 {
1206 LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL; 1294 LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
1207 args["[OBJECTTYPE]"] = ""; 1295 args["OBJECTTYPE"] = "";
1208 1296
1209 // This seems safest, rather than propagating bogosity 1297 // This seems safest, rather than propagating bogosity
1210 LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL; 1298 LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
1211 inventory_offer_callback(IOR_DECLINE, info); 1299 info->forceResponse(IOR_DECLINE);
1212 return; 1300 return;
1213 } 1301 }
1214 1302
1215 // Name cache callbacks don't store userdata, so can't save 1303 // Name cache callbacks don't store userdata, so can't save
1216 // off the LLOfferInfo. Argh. JC 1304 // off the LLOfferInfo. Argh.
1217 BOOL name_found = FALSE; 1305 BOOL name_found = FALSE;
1218 if (info->mFromGroup) 1306 if (info->mFromGroup)
1219 { 1307 {
1220 std::string group_name; 1308 std::string group_name;
1221 if (gCacheName->getGroupName(info->mFromID, group_name)) 1309 if (gCacheName->getGroupName(info->mFromID, group_name))
1222 { 1310 {
1223 args["[FIRST]"] = group_name; 1311 args["FIRST"] = group_name;
1224 args["[LAST]"] = ""; 1312 args["LAST"] = "";
1225 name_found = TRUE; 1313 name_found = TRUE;
1226 } 1314 }
1227 } 1315 }
@@ -1230,95 +1318,100 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1230 std::string first_name, last_name; 1318 std::string first_name, last_name;
1231 if (gCacheName->getName(info->mFromID, first_name, last_name)) 1319 if (gCacheName->getName(info->mFromID, first_name, last_name))
1232 { 1320 {
1233 args["[FIRST]"] = first_name; 1321 args["FIRST"] = first_name;
1234 args["[LAST]"] = last_name; 1322 args["LAST"] = last_name;
1235 name_found = TRUE; 1323 name_found = TRUE;
1236 } 1324 }
1237 } 1325 }
1326
1327 payload["from_id"] = info->mFromID;
1328 args["OBJECTFROMNAME"] = info->mFromName;
1329 args["NAME"] = info->mFromName;
1330
1331 LLNotification::Params p("ObjectGiveItem");
1332 p.substitutions(args).payload(payload).functor(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
1333
1238 if (from_task) 1334 if (from_task)
1239 { 1335 {
1240 args["[OBJECTFROMNAME]"] = info->mFromName; 1336 p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser";
1241 LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser",
1242 args, &inventory_offer_callback, (void*)info);
1243 } 1337 }
1244 else 1338 else
1245 { 1339 {
1246 // *TODO:translate -> [FIRST] [LAST] 1340 p.name = "UserGiveItem";
1247 args["[NAME]"] = info->mFromName;
1248 LLNotifyBox::showXml("UserGiveItem", args,
1249 &inventory_offer_callback, (void*)info);
1250 } 1341 }
1342
1343 LLNotifications::instance().add(p);
1251} 1344}
1252 1345
1253 1346
1254void group_vote_callback(S32 option, void *userdata) 1347bool group_vote_callback(const LLSD& notification, const LLSD& response)
1255{ 1348{
1256 LLUUID *group_id = (LLUUID *)userdata; 1349 LLUUID group_id = notification["payload"]["group_id"].asUUID();
1257 if (!group_id) return; 1350 S32 option = LLNotification::getSelectedOption(notification, response);
1258
1259 switch(option) 1351 switch(option)
1260 { 1352 {
1261 case 0: 1353 case 0:
1262 // Vote Now 1354 // Vote Now
1263 // Open up the voting tab 1355 // Open up the voting tab
1264 LLFloaterGroupInfo::showFromUUID(*group_id, "voting_tab"); 1356 LLFloaterGroupInfo::showFromUUID(group_id, "voting_tab");
1265 break; 1357 break;
1266 default: 1358 default:
1267 // Vote Later or 1359 // Vote Later or
1268 // close button 1360 // close button
1269 break; 1361 break;
1270 } 1362 }
1271 delete group_id; 1363 return false;
1272 group_id = NULL;
1273} 1364}
1365static LLNotificationFunctorRegistration group_vote_callback_reg("GroupVote", group_vote_callback);
1274 1366
1275struct LLLureInfo 1367bool lure_callback(const LLSD& notification, const LLSD& response)
1276{ 1368{
1277 LLLureInfo(const LLUUID& from, const LLUUID& lure_id, BOOL godlike) : 1369 S32 option = 0;
1278 mFromID(from), 1370 if (response.isInteger())
1279 mLureID(lure_id), 1371 {
1280 mGodlike(godlike) 1372 option = response.asInteger();
1281 {} 1373 }
1282 1374 else
1283 LLUUID mFromID; 1375 {
1284 LLUUID mLureID; 1376 option = LLNotification::getSelectedOption(notification, response);
1285 BOOL mGodlike; 1377 }
1286}; 1378
1379 LLUUID from_id = notification["payload"]["from_id"].asUUID();
1380 LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
1381 BOOL godlike = notification["payload"]["godlike"].asBoolean();
1287 1382
1288void lure_callback(S32 option, void* user_data)
1289{
1290 LLLureInfo* info = (LLLureInfo*)user_data;
1291 if(!info) return;
1292 switch(option) 1383 switch(option)
1293 { 1384 {
1294 case 0: 1385 case 0:
1295 { 1386 {
1296 // accept 1387 // accept
1297 gAgent.teleportViaLure(info->mLureID, info->mGodlike); 1388 gAgent.teleportViaLure(lure_id, godlike);
1298 } 1389 }
1299 break; 1390 break;
1300 case 1: 1391 case 1:
1301 default: 1392 default:
1302 // decline 1393 // decline
1303 send_simple_im(info->mFromID, 1394 send_simple_im(from_id,
1304 LLStringUtil::null, 1395 LLStringUtil::null,
1305 IM_LURE_DECLINED, 1396 IM_LURE_DECLINED,
1306 info->mLureID); 1397 lure_id);
1307 break; 1398 break;
1308 } 1399 }
1309 delete info; 1400 return false;
1310 info = NULL;
1311} 1401}
1402static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
1312 1403
1313void goto_url_callback(S32 option, void* user_data) 1404bool goto_url_callback(const LLSD& notification, const LLSD& response)
1314{ 1405{
1315 char* url = (char*)user_data; 1406 std::string url = notification["payload"]["url"].asString();
1407 S32 option = LLNotification::getSelectedOption(notification, response);
1316 if(1 == option) 1408 if(1 == option)
1317 { 1409 {
1318 LLWeb::loadURL(url); 1410 LLWeb::loadURL(url);
1319 } 1411 }
1320 delete[] url; 1412 return false;
1321} 1413}
1414static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
1322 1415
1323void process_improved_im(LLMessageSystem *msg, void **user_data) 1416void process_improved_im(LLMessageSystem *msg, void **user_data)
1324{ 1417{
@@ -1332,7 +1425,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1332 U8 offline; 1425 U8 offline;
1333 U8 d = 0; 1426 U8 d = 0;
1334 LLUUID session_id; 1427 LLUUID session_id;
1335 U32 t; 1428 U32 timestamp;
1336 std::string name; 1429 std::string name;
1337 std::string message; 1430 std::string message;
1338 U32 parent_estate_id = 0; 1431 U32 parent_estate_id = 0;
@@ -1350,7 +1443,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1350 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline); 1443 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline);
1351 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d); 1444 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d);
1352 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id); 1445 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
1353 msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, t); 1446 msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
1354 //msg->getData("MessageBlock", "Count", &count); 1447 //msg->getData("MessageBlock", "Count", &count);
1355 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name); 1448 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
1356 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message); 1449 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message);
@@ -1360,7 +1453,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1360 msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES); 1453 msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
1361 binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket); 1454 binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
1362 EInstantMessage dialog = (EInstantMessage)d; 1455 EInstantMessage dialog = (EInstantMessage)d;
1363 time_t timestamp = (time_t)t;
1364 1456
1365 BOOL is_busy = gAgent.getBusy(); 1457 BOOL is_busy = gAgent.getBusy();
1366 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); 1458 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
@@ -1389,18 +1481,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1389 message_offset = 3; 1481 message_offset = 3;
1390 } 1482 }
1391 1483
1392 LLStringUtil::format_map_t args; 1484 LLSD args;
1393 switch(dialog) 1485 switch(dialog)
1394 { 1486 {
1395 case IM_CONSOLE_AND_CHAT_HISTORY: 1487 case IM_CONSOLE_AND_CHAT_HISTORY:
1396 // These are used for system messages, hence don't need the name, 1488 // These are used for system messages, hence don't need the name,
1397 // as it is always "Second Life". 1489 // as it is always "Second Life".
1398 // *TODO:translate 1490 // *TODO:translate
1399 args["[MESSAGE]"] = message; 1491 args["MESSAGE"] = message;
1400 1492
1401 // Note: don't put the message in the IM history, even though was sent 1493 // Note: don't put the message in the IM history, even though was sent
1402 // via the IM mechanism. 1494 // via the IM mechanism.
1403 LLNotifyBox::showXml("SystemMessageTip",args); 1495 LLNotifications::instance().add("SystemMessageTip",args);
1404 break; 1496 break;
1405 1497
1406 case IM_NOTHING_SPECIAL: 1498 case IM_NOTHING_SPECIAL:
@@ -1470,9 +1562,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1470 else if (to_id.isNull()) 1562 else if (to_id.isNull())
1471 { 1563 {
1472 // Message to everyone from GOD 1564 // Message to everyone from GOD
1473 args["[NAME]"] = name; 1565 args["NAME"] = name;
1474 args["[MESSAGE]"] = message; 1566 args["MESSAGE"] = message;
1475 LLNotifyBox::showXml("GodMessage", args); 1567 LLNotifications::instance().add("GodMessage", args);
1476 1568
1477 // Treat like a system message and put in chat history. 1569 // Treat like a system message and put in chat history.
1478 // Claim to be from a local agent so it doesn't go into 1570 // Claim to be from a local agent so it doesn't go into
@@ -1541,8 +1633,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1541 { 1633 {
1542 // This is a block, modeless dialog. 1634 // This is a block, modeless dialog.
1543 //*TODO:translate 1635 //*TODO:translate
1544 args["[MESSAGE]"] = message; 1636 args["MESSAGE"] = message;
1545 LLNotifyBox::showXml("SystemMessage", args); 1637 LLNotifications::instance().add("SystemMessage", args);
1546 } 1638 }
1547 break; 1639 break;
1548 case IM_GROUP_NOTICE: 1640 case IM_GROUP_NOTICE:
@@ -1579,9 +1671,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1579 1671
1580 // If there is inventory, give the user the inventory offer. 1672 // If there is inventory, give the user the inventory offer.
1581 LLOfferInfo* info = NULL; 1673 LLOfferInfo* info = NULL;
1674
1582 if (has_inventory) 1675 if (has_inventory)
1583 { 1676 {
1584 info = new LLOfferInfo; 1677 info = new LLOfferInfo;
1678
1585 info->mIM = IM_GROUP_NOTICE; 1679 info->mIM = IM_GROUP_NOTICE;
1586 info->mFromID = from_id; 1680 info->mFromID = from_id;
1587 info->mFromGroup = from_group; 1681 info->mFromGroup = from_group;
@@ -1610,13 +1704,26 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1610 std::string subj(*iter++); 1704 std::string subj(*iter++);
1611 std::string mes(*iter++); 1705 std::string mes(*iter++);
1612 1706
1613 if (IM_GROUP_NOTICE == dialog) 1707 // Send the notification down the new path.
1708 // For requested notices, we don't want to send the popups.
1709 if (dialog != IM_GROUP_NOTICE_REQUESTED)
1614 { 1710 {
1615 subj += "\n"; 1711 LLSD payload;
1616 mes = "\n\n" + mes; 1712 payload["subject"] = subj;
1617 LLGroupNotifyBox::show(subj,mes,name,group_id,t,has_inventory,item_name,info); 1713 payload["message"] = mes;
1714 payload["sender_name"] = name;
1715 payload["group_id"] = group_id;
1716 payload["inventory_name"] = item_name;
1717 payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
1718
1719 LLSD args;
1720 args["SUBJECT"] = subj;
1721 args["MESSAGE"] = mes;
1722 LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
1618 } 1723 }
1619 else if (IM_GROUP_NOTICE_REQUESTED == dialog) 1724
1725 // Also send down the old path for now.
1726 if (IM_GROUP_NOTICE_REQUESTED == dialog)
1620 { 1727 {
1621 LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info); 1728 LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info);
1622 } 1729 }
@@ -1628,7 +1735,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1628 if ((is_busy || is_muted)) 1735 if ((is_busy || is_muted))
1629 { 1736 {
1630 LLMessageSystem *msg = gMessageSystem; 1737 LLMessageSystem *msg = gMessageSystem;
1631 join_group_callback(1, NULL);
1632 busy_message(msg,from_id); 1738 busy_message(msg,from_id);
1633 } 1739 }
1634 else 1740 else
@@ -1651,18 +1757,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1651 invite_bucket = (struct invite_bucket_t*) &binary_bucket[0]; 1757 invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
1652 S32 membership_fee = ntohl(invite_bucket->membership_fee); 1758 S32 membership_fee = ntohl(invite_bucket->membership_fee);
1653 1759
1654 LLJoinGroupData* userdata = new LLJoinGroupData; 1760 LLSD payload;
1655 userdata->mTransactionID = session_id; 1761 payload["transaction_id"] = session_id;
1656 userdata->mGroupID = from_id; 1762 payload["group_id"] = from_id;
1657 userdata->mName.assign(name); 1763 payload["name"] = name;
1658 userdata->mMessage.assign(message); 1764 payload["message"] = message;
1659 userdata->mFee = membership_fee; 1765 payload["fee"] = membership_fee;
1660 1766
1661 LLStringUtil::format_map_t args; 1767 LLSD args;
1662 args["[MESSAGE]"] = message; 1768 args["MESSAGE"] = message;
1663 LLNotifyBox::showXml("JoinGroup", args, 1769 LLNotifications::instance().add("JoinGroup", args, payload, join_group_response);
1664 &join_group_callback,
1665 (void*)userdata);
1666 } 1770 }
1667 } 1771 }
1668 break; 1772 break;
@@ -1722,7 +1826,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1722 if ( is_muted ) 1826 if ( is_muted )
1723 { 1827 {
1724 // Same as closing window 1828 // Same as closing window
1725 inventory_offer_callback(-1, info); 1829 info->forceResponse(IOR_DECLINE);
1726 } 1830 }
1727 else 1831 else
1728 { 1832 {
@@ -1733,23 +1837,25 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1733 1837
1734 case IM_INVENTORY_ACCEPTED: 1838 case IM_INVENTORY_ACCEPTED:
1735 { 1839 {
1736 args["[NAME]"] = name; 1840 args["NAME"] = name;
1737 LLNotifyBox::showXml("InventoryAccepted", args); 1841 LLNotifications::instance().add("InventoryAccepted", args);
1738 break; 1842 break;
1739 } 1843 }
1740 case IM_INVENTORY_DECLINED: 1844 case IM_INVENTORY_DECLINED:
1741 { 1845 {
1742 args["[NAME]"] = name; 1846 args["NAME"] = name;
1743 LLNotifyBox::showXml("InventoryDeclined", args); 1847 LLNotifications::instance().add("InventoryDeclined", args);
1744 break; 1848 break;
1745 } 1849 }
1746 case IM_GROUP_VOTE: 1850 case IM_GROUP_VOTE:
1747 { 1851 {
1748 LLUUID *userdata = new LLUUID(session_id); 1852 LLSD args;
1749 args["[NAME]"] = name; 1853 args["NAME"] = name;
1750 args["[MESSAGE]"] = message; 1854 args["MESSAGE"] = message;
1751 LLNotifyBox::showXml("GroupVote", args, 1855
1752 &group_vote_callback, userdata); 1856 LLSD payload;
1857 payload["group_id"] = session_id;
1858 LLNotifications::instance().add("GroupVote", args, payload);
1753 } 1859 }
1754 break; 1860 break;
1755 1861
@@ -1803,15 +1909,52 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1803 break; 1909 break;
1804 1910
1805 case IM_FROM_TASK: 1911 case IM_FROM_TASK:
1806 if (is_busy && !is_owned_by_me)
1807 { 1912 {
1808 return; 1913 if (is_busy && !is_owned_by_me)
1914 {
1915 return;
1916 }
1917 chat.mText = name + separator_string + message.substr(message_offset);
1918 chat.mFromName = name;
1919
1920 // Build a link to open the object IM info window.
1921 std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size);
1922
1923 LLSD query_string;
1924 query_string["owner"] = from_id;
1925 query_string["slurl"] = location.c_str();
1926 query_string["name"] = name;
1927 if (from_group)
1928 {
1929 query_string["groupowned"] = "true";
1930 }
1931
1932 if (session_id.notNull())
1933 {
1934 chat.mFromID = session_id;
1935 }
1936 else
1937 {
1938 // This message originated on a region without the updated code for task id and slurl information.
1939 // We just need a unique ID for this object that isn't the owner ID.
1940 // If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
1941 // This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
1942 // This works because the only thing we can really do in this case is show the owner name and link to their profile.
1943 chat.mFromID = from_id ^ gAgent.getSessionID();
1944 }
1945
1946 std::ostringstream link;
1947 link << "secondlife:///app/objectim/" << session_id
1948 << LLURI::mapToQueryString(query_string);
1949
1950 chat.mURL = link.str();
1951 chat.mText = name + separator_string + message.substr(message_offset);
1952
1953 // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
1954 // IMs from objcts don't open IM sessions.
1955 chat.mSourceType = CHAT_SOURCE_OBJECT;
1956 LLFloaterChat::addChat(chat, FALSE, FALSE);
1809 } 1957 }
1810 chat.mText = name + separator_string + message.substr(message_offset);
1811 // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
1812 // IMs from objcts don't open IM sessions.
1813 chat.mSourceType = CHAT_SOURCE_OBJECT;
1814 LLFloaterChat::addChat(chat, FALSE, FALSE);
1815 break; 1958 break;
1816 case IM_FROM_TASK_AS_ALERT: 1959 case IM_FROM_TASK_AS_ALERT:
1817 if (is_busy && !is_owned_by_me) 1960 if (is_busy && !is_owned_by_me)
@@ -1820,9 +1963,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1820 } 1963 }
1821 { 1964 {
1822 // Construct a viewer alert for this message. 1965 // Construct a viewer alert for this message.
1823 args["[NAME]"] = name; 1966 args["NAME"] = name;
1824 args["[MESSAGE]"] = message; 1967 args["MESSAGE"] = message;
1825 LLNotifyBox::showXml("ObjectMessage", args); 1968 LLNotifications::instance().add("ObjectMessage", args);
1826 } 1969 }
1827 break; 1970 break;
1828 case IM_BUSY_AUTO_RESPONSE: 1971 case IM_BUSY_AUTO_RESPONSE:
@@ -1851,27 +1994,34 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1851 } 1994 }
1852 else 1995 else
1853 { 1996 {
1997 LLSD args;
1854 // *TODO:translate -> [FIRST] [LAST] (maybe) 1998 // *TODO:translate -> [FIRST] [LAST] (maybe)
1855 LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE); 1999 args["NAME"] = name;
1856 args["[NAME]"] = name; 2000 args["MESSAGE"] = message;
1857 args["[MESSAGE]"] = message; 2001 LLSD payload;
1858 LLNotifyBox::showXml("OfferTeleport", args, 2002 payload["from_id"] = from_id;
1859 lure_callback, (void*)info); 2003 payload["lure_id"] = session_id;
2004 payload["godlike"] = FALSE;
2005 LLNotifications::instance().add("TeleportOffered", args, payload);
1860 } 2006 }
1861 } 2007 }
1862 break; 2008 break;
1863 2009
1864 case IM_GODLIKE_LURE_USER: 2010 case IM_GODLIKE_LURE_USER:
1865 { 2011 {
1866 LLLureInfo* info = new LLLureInfo(from_id, session_id, TRUE); 2012 LLSD payload;
2013 payload["from_id"] = from_id;
2014 payload["lure_id"] = session_id;
2015 payload["godlike"] = TRUE;
1867 // do not show a message box, because you're about to be 2016 // do not show a message box, because you're about to be
1868 // teleported. 2017 // teleported.
1869 lure_callback(0, (void *)info); 2018 LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
1870 } 2019 }
1871 break; 2020 break;
1872 2021
1873 case IM_GOTO_URL: 2022 case IM_GOTO_URL:
1874 { 2023 {
2024 LLSD args;
1875 // n.b. this is for URLs sent by the system, not for 2025 // n.b. this is for URLs sent by the system, not for
1876 // URLs sent by scripts (i.e. llLoadURL) 2026 // URLs sent by scripts (i.e. llLoadURL)
1877 if (binary_bucket_size <= 0) 2027 if (binary_bucket_size <= 0)
@@ -1882,38 +2032,33 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1882 return; 2032 return;
1883 } 2033 }
1884 2034
1885 char* url = new char[binary_bucket_size]; 2035 std::string url;
1886 if (url == NULL) 2036
1887 { 2037 url.assign((char*)binary_bucket, binary_bucket_size-1);
1888 LL_ERRS("Messaging") << "Memory Allocation failed" << LL_ENDL; 2038 args["MESSAGE"] = message;
1889 return; 2039 args["URL"] = url;
1890 } 2040 LLSD payload;
1891 2041 payload["url"] = url;
1892 strncpy(url, (char*)binary_bucket, binary_bucket_size-1); /* Flawfinder: ignore */ 2042 LLNotifications::instance().add("GotoURL", args, payload );
1893 url[binary_bucket_size-1] = '\0';
1894 args["[MESSAGE]"] = message;
1895 args["[URL]"] = url;
1896 LLNotifyBox::showXml("GotoURL", args,
1897 goto_url_callback, (void*)url);
1898 } 2043 }
1899 break; 2044 break;
1900 2045
1901 case IM_FRIENDSHIP_OFFERED: 2046 case IM_FRIENDSHIP_OFFERED:
1902 { 2047 {
1903 LLFriendshipOffer* offer = new LLFriendshipOffer; 2048 LLSD payload;
1904 offer->mFromID = from_id; 2049 payload["from_id"] = from_id;
1905 offer->mTransactionID = session_id; 2050 payload["session_id"] = session_id;;
1906 offer->mOnline = (offline == IM_ONLINE); 2051 payload["online"] = (offline == IM_ONLINE);
1907 offer->mHost = msg->getSender(); 2052 payload["sender"] = msg->getSender().getIPandPort();
1908 2053
1909 if (is_busy) 2054 if (is_busy)
1910 { 2055 {
1911 busy_message(msg, from_id); 2056 busy_message(msg, from_id);
1912 friendship_offer_callback(1, (void*)offer); 2057 LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
1913 } 2058 }
1914 else if (is_muted) 2059 else if (is_muted)
1915 { 2060 {
1916 friendship_offer_callback(1, (void*)offer); 2061 LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
1917 } 2062 }
1918 else 2063 else
1919 { 2064 {
@@ -1921,14 +2066,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1921 if(message.empty()) 2066 if(message.empty())
1922 { 2067 {
1923 //support for frienship offers from clients before July 2008 2068 //support for frienship offers from clients before July 2008
1924 LLNotifyBox::showXml("OfferFriendshipNoMessage", args, 2069 LLNotifications::instance().add("OfferFriendshipNoMessage", args, payload);
1925 &friendship_offer_callback, (void*)offer);
1926 } 2070 }
1927 else 2071 else
1928 { 2072 {
1929 args["[MESSAGE]"] = message; 2073 args["[MESSAGE]"] = message;
1930 LLNotifyBox::showXml("OfferFriendship", args, 2074 LLNotifications::instance().add("OfferFriendship", args, payload);
1931 &friendship_offer_callback, (void*)offer);
1932 } 2075 }
1933 } 2076 }
1934 } 2077 }
@@ -1945,16 +2088,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1945 strings.push_back(from_id.asString()); 2088 strings.push_back(from_id.asString());
1946 send_generic_message("requestonlinenotification", strings); 2089 send_generic_message("requestonlinenotification", strings);
1947 2090
1948 args["[NAME]"] = name; 2091 args["NAME"] = name;
1949 LLNotifyBox::showXml("FriendshipAccepted", args); 2092 LLNotifications::instance().add("FriendshipAccepted", args);
1950 } 2093 }
1951 break; 2094 break;
1952 2095
1953 case IM_FRIENDSHIP_DECLINED: 2096 case IM_FRIENDSHIP_DECLINED_DEPRECATED:
1954 args["[NAME]"] = name;
1955 LLNotifyBox::showXml("FriendshipDeclined", args);
1956 break;
1957
1958 default: 2097 default:
1959 LL_WARNS("Messaging") << "Instant message calling for unknown dialog " 2098 LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
1960 << (S32)dialog << LL_ENDL; 2099 << (S32)dialog << LL_ENDL;
@@ -1989,61 +2128,9 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
1989 } 2128 }
1990} 2129}
1991 2130
1992void friendship_offer_callback(S32 option, void* user_data) 2131bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
1993{
1994 LLFriendshipOffer* offer = (LLFriendshipOffer*)user_data;
1995 if(!offer) return;
1996 LLUUID fid;
1997 LLMessageSystem* msg = gMessageSystem;
1998 switch(option)
1999 {
2000 case 0:
2001 // accept
2002 LLAvatarTracker::formFriendship(offer->mFromID);
2003
2004 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
2005
2006 // This will also trigger an onlinenotification if the user is online
2007 msg->newMessageFast(_PREHASH_AcceptFriendship);
2008 msg->nextBlockFast(_PREHASH_AgentData);
2009 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2010 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2011 msg->nextBlockFast(_PREHASH_TransactionBlock);
2012 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
2013 msg->nextBlockFast(_PREHASH_FolderData);
2014 msg->addUUIDFast(_PREHASH_FolderID, fid);
2015 msg->sendReliable(offer->mHost);
2016 break;
2017 case 1:
2018 // decline
2019 msg->newMessageFast(_PREHASH_DeclineFriendship);
2020 msg->nextBlockFast(_PREHASH_AgentData);
2021 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2022 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2023 msg->nextBlockFast(_PREHASH_TransactionBlock);
2024 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
2025 msg->sendReliable(offer->mHost);
2026 break;
2027 default:
2028 // close button probably, possibly timed out
2029 break;
2030 }
2031
2032 delete offer;
2033 offer = NULL;
2034}
2035
2036struct LLCallingCardOfferData
2037{ 2132{
2038 LLUUID mTransactionID; 2133 S32 option = LLNotification::getSelectedOption(notification, response);
2039 LLUUID mSourceID;
2040 LLHost mHost;
2041};
2042
2043void callingcard_offer_callback(S32 option, void* user_data)
2044{
2045 LLCallingCardOfferData* offerdata = (LLCallingCardOfferData*)user_data;
2046 if(!offerdata) return;
2047 LLUUID fid; 2134 LLUUID fid;
2048 LLUUID from_id; 2135 LLUUID from_id;
2049 LLMessageSystem* msg = gMessageSystem; 2136 LLMessageSystem* msg = gMessageSystem;
@@ -2056,11 +2143,11 @@ void callingcard_offer_callback(S32 option, void* user_data)
2056 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 2143 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2057 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 2144 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2058 msg->nextBlockFast(_PREHASH_TransactionBlock); 2145 msg->nextBlockFast(_PREHASH_TransactionBlock);
2059 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID); 2146 msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
2060 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); 2147 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
2061 msg->nextBlockFast(_PREHASH_FolderData); 2148 msg->nextBlockFast(_PREHASH_FolderData);
2062 msg->addUUIDFast(_PREHASH_FolderID, fid); 2149 msg->addUUIDFast(_PREHASH_FolderID, fid);
2063 msg->sendReliable(offerdata->mHost); 2150 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
2064 break; 2151 break;
2065 case 1: 2152 case 1:
2066 // decline 2153 // decline
@@ -2069,18 +2156,18 @@ void callingcard_offer_callback(S32 option, void* user_data)
2069 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 2156 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2070 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 2157 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2071 msg->nextBlockFast(_PREHASH_TransactionBlock); 2158 msg->nextBlockFast(_PREHASH_TransactionBlock);
2072 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID); 2159 msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
2073 msg->sendReliable(offerdata->mHost); 2160 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
2074 busy_message(msg, offerdata->mSourceID); 2161 busy_message(msg, notification["payload"]["source_id"].asUUID());
2075 break; 2162 break;
2076 default: 2163 default:
2077 // close button probably, possibly timed out 2164 // close button probably, possibly timed out
2078 break; 2165 break;
2079 } 2166 }
2080 2167
2081 delete offerdata; 2168 return false;
2082 offerdata = NULL;
2083} 2169}
2170static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback);
2084 2171
2085void process_offer_callingcard(LLMessageSystem* msg, void**) 2172void process_offer_callingcard(LLMessageSystem* msg, void**)
2086{ 2173{
@@ -2092,13 +2179,13 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2092 LLUUID tid; 2179 LLUUID tid;
2093 msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid); 2180 msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
2094 2181
2095 LLCallingCardOfferData* offerdata = new LLCallingCardOfferData; 2182 LLSD payload;
2096 offerdata->mTransactionID = tid; 2183 payload["transaction_id"] = tid;
2097 offerdata->mSourceID = source_id; 2184 payload["source_id"] = source_id;
2098 offerdata->mHost = msg->getSender(); 2185 payload["sender"] = msg->getSender().getIPandPort();
2099 2186
2100 LLViewerObject* source = gObjectList.findObject(source_id); 2187 LLViewerObject* source = gObjectList.findObject(source_id);
2101 LLStringUtil::format_map_t args; 2188 LLSD args;
2102 std::string source_name; 2189 std::string source_name;
2103 if(source && source->isAvatar()) 2190 if(source && source->isAvatar())
2104 { 2191 {
@@ -2106,8 +2193,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2106 LLNameValue* nvlast = source->getNVPair("LastName"); 2193 LLNameValue* nvlast = source->getNVPair("LastName");
2107 if (nvfirst && nvlast) 2194 if (nvfirst && nvlast)
2108 { 2195 {
2109 args["[FIRST]"] = nvfirst->getString(); 2196 args["FIRST"] = nvfirst->getString();
2110 args["[LAST]"] = nvlast->getString(); 2197 args["LAST"] = nvlast->getString();
2111 source_name = std::string(nvfirst->getString()) + " " + nvlast->getString(); 2198 source_name = std::string(nvfirst->getString()) + " " + nvlast->getString();
2112 } 2199 }
2113 } 2200 }
@@ -2118,33 +2205,27 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2118 || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat)) 2205 || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
2119 { 2206 {
2120 // automatically decline offer 2207 // automatically decline offer
2121 callingcard_offer_callback(1, (void*)offerdata); 2208 LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1);
2122 offerdata = NULL; // pointer was freed by callback
2123 } 2209 }
2124 else 2210 else
2125 { 2211 {
2126 LLNotifyBox::showXml("OfferCallingCard", args, 2212 LLNotifications::instance().add("OfferCallingCard", args, payload);
2127 &callingcard_offer_callback, (void*)offerdata);
2128 offerdata = NULL; // pointer ownership transferred
2129 } 2213 }
2130 } 2214 }
2131 else 2215 else
2132 { 2216 {
2133 LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL; 2217 LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
2134 } 2218 }
2135
2136 delete offerdata; // !=NULL if we didn't give ownership away
2137 offerdata = NULL;
2138} 2219}
2139 2220
2140void process_accept_callingcard(LLMessageSystem* msg, void**) 2221void process_accept_callingcard(LLMessageSystem* msg, void**)
2141{ 2222{
2142 LLNotifyBox::showXml("CallingCardAccepted"); 2223 LLNotifications::instance().add("CallingCardAccepted");
2143} 2224}
2144 2225
2145void process_decline_callingcard(LLMessageSystem* msg, void**) 2226void process_decline_callingcard(LLMessageSystem* msg, void**)
2146{ 2227{
2147 LLNotifyBox::showXml("CallingCardDeclined"); 2228 LLNotifications::instance().add("CallingCardDeclined");
2148} 2229}
2149 2230
2150 2231
@@ -2460,18 +2541,18 @@ public:
2460 LLInventoryModel::EXCLUDE_TRASH, 2541 LLInventoryModel::EXCLUDE_TRASH,
2461 is_card); 2542 is_card);
2462 } 2543 }
2463 LLStringUtil::format_map_t args; 2544 LLSD args;
2464 if ( land_items.count() > 0 ) 2545 if ( land_items.count() > 0 )
2465 { // Show notification that they can now teleport to landmarks. Use a random landmark from the inventory 2546 { // Show notification that they can now teleport to landmarks. Use a random landmark from the inventory
2466 S32 random_land = ll_rand( land_items.count() - 1 ); 2547 S32 random_land = ll_rand( land_items.count() - 1 );
2467 args["[NAME]"] = land_items[random_land]->getName(); 2548 args["NAME"] = land_items[random_land]->getName();
2468 LLNotifyBox::showXml("TeleportToLandmark",args); 2549 LLNotifications::instance().add("TeleportToLandmark",args);
2469 } 2550 }
2470 if ( card_items.count() > 0 ) 2551 if ( card_items.count() > 0 )
2471 { // Show notification that they can now contact people. Use a random calling card from the inventory 2552 { // Show notification that they can now contact people. Use a random calling card from the inventory
2472 S32 random_card = ll_rand( card_items.count() - 1 ); 2553 S32 random_card = ll_rand( card_items.count() - 1 );
2473 args["[NAME]"] = card_items[random_card]->getName(); 2554 args["NAME"] = card_items[random_card]->getName();
2474 LLNotifyBox::showXml("TeleportToPerson",args); 2555 LLNotifications::instance().add("TeleportToPerson",args);
2475 } 2556 }
2476 2557
2477 gInventory.removeObserver(this); 2558 gInventory.removeObserver(this);
@@ -2652,11 +2733,6 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
2652} 2733}
2653*/ 2734*/
2654 2735
2655static void display_release_notes(S32, void* data)
2656{
2657 gAgent.getRegion()->showReleaseNotes();
2658}
2659
2660void process_agent_movement_complete(LLMessageSystem* msg, void**) 2736void process_agent_movement_complete(LLMessageSystem* msg, void**)
2661{ 2737{
2662 gAgentMovementCompleted = true; 2738 gAgentMovementCompleted = true;
@@ -2690,7 +2766,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2690 if (!avatarp) 2766 if (!avatarp)
2691 { 2767 {
2692 // Could happen if you were immediately god-teleported away on login, 2768 // Could happen if you were immediately god-teleported away on login,
2693 // maybe other cases. Continue, but warn. JC 2769 // maybe other cases. Continue, but warn.
2694 LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL; 2770 LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
2695 } 2771 }
2696 2772
@@ -2730,7 +2806,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2730 2806
2731 if( is_teleport ) 2807 if( is_teleport )
2732 { 2808 {
2733 // Force the camera back onto the agent, don't animate. JC 2809 // Force the camera back onto the agent, don't animate.
2734 gAgent.setFocusOnAvatar(TRUE, FALSE); 2810 gAgent.setFocusOnAvatar(TRUE, FALSE);
2735 gAgent.slamLookAt(look_at); 2811 gAgent.slamLookAt(look_at);
2736 gAgent.updateCamera(); 2812 gAgent.updateCamera();
@@ -2828,8 +2904,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2828 2904
2829 if (!gLastVersionChannel.empty()) 2905 if (!gLastVersionChannel.empty())
2830 { 2906 {
2831 LLNotifyBox::showXml( 2907 LLSD payload;
2832 "ServerVersionChanged", display_release_notes, NULL); 2908 payload["message"] = version_channel;
2909 LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload);
2833 } 2910 }
2834 2911
2835 gLastVersionChannel = version_channel; 2912 gLastVersionChannel = version_channel;
@@ -3308,6 +3385,12 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3308 return; 3385 return;
3309 } 3386 }
3310 3387
3388 // Don't play sounds from a region with maturity above current agent maturity
3389 if( !gAgent.canAccessMaturityInRegion( region_handle ) )
3390 {
3391 return;
3392 }
3393
3311 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global); 3394 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
3312} 3395}
3313 3396
@@ -3341,6 +3424,13 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
3341 // audio data into a buffer at this point, as it won't actually 3424 // audio data into a buffer at this point, as it won't actually
3342 // help us out. 3425 // help us out.
3343 3426
3427 // Don't play sounds from a region with maturity above current agent maturity
3428 LLVector3d pos_global = objectp->getPositionGlobal();
3429 if( !gAgent.canAccessMaturityAtGlobal( pos_global ) )
3430 {
3431 return;
3432 }
3433
3344 // Add audioData starts a transfer internally. 3434 // Add audioData starts a transfer internally.
3345 sourcep->addAudioData(datap, FALSE); 3435 sourcep->addAudioData(datap, FALSE);
3346} 3436}
@@ -3370,6 +3460,14 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
3370 3460
3371 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return; 3461 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
3372 3462
3463
3464 // Don't play sounds from a region with maturity above current agent maturity
3465 LLVector3d pos = objectp->getPositionGlobal();
3466 if( !gAgent.canAccessMaturityAtGlobal(pos) )
3467 {
3468 return;
3469 }
3470
3373 objectp->setAttachedSound(sound_id, owner_id, gain, flags); 3471 objectp->setAttachedSound(sound_id, owner_id, gain, flags);
3374} 3472}
3375 3473
@@ -3592,7 +3690,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
3592 3690
3593 avatarp->mSignaledAnimations.clear(); 3691 avatarp->mSignaledAnimations.clear();
3594 3692
3595 if (avatarp->mIsSelf) 3693 if (avatarp->isSelf())
3596 { 3694 {
3597 LLUUID object_id; 3695 LLUUID object_id;
3598 3696
@@ -4023,9 +4121,9 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
4023 // Make the user confirm the transaction, since they might 4121 // Make the user confirm the transaction, since they might
4024 // have missed something during an event. 4122 // have missed something during an event.
4025 // *TODO:translate 4123 // *TODO:translate
4026 LLStringUtil::format_map_t args; 4124 LLSD args;
4027 args["[MESSAGE]"] = desc; 4125 args["MESSAGE"] = desc;
4028 LLNotifyBox::showXml("SystemMessage", args); 4126 LLNotifications::instance().add("SystemMessage", args);
4029 4127
4030 // Once the 'recent' container gets large enough, chop some 4128 // Once the 'recent' container gets large enough, chop some
4031 // off the beginning. 4129 // off the beginning.
@@ -4041,29 +4139,158 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
4041 } 4139 }
4042} 4140}
4043 4141
4044void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data) 4142bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
4045{ 4143{
4046 std::string buffer; 4144 S32 option = LLNotification::getSelectedOption(notification, response);
4047 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); 4145
4048 BOOL modal = FALSE; 4146 if (0 == option)
4049 msgsystem->getBOOL("AlertData", "Modal", modal); 4147 {
4050 process_alert_core(buffer, modal); 4148 // set the preference to the maturity of the region we're calling
4149 int preferredMaturity = notification["payload"]["_region_access"].asInteger();
4150 gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
4151 gAgent.sendMaturityPreferenceToServer(preferredMaturity);
4152
4153 }
4154
4155 return false;
4051} 4156}
4052 4157
4053void process_alert_message(LLMessageSystem *msgsystem, void **user_data) 4158// some of the server notifications need special handling. This is where we do that.
4159bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
4054{ 4160{
4055 std::string buffer; 4161 int regionAccess = llsdBlock["_region_access"].asInteger();
4056 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); 4162 llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
4057 BOOL modal = FALSE; 4163
4058 process_alert_core(buffer, modal); 4164 // we're going to throw the LLSD in there in case anyone ever wants to use it
4165 LLNotifications::instance().add(notificationID+"_Notify", llsdBlock);
4166
4167 if (regionAccess == SIM_ACCESS_MATURE)
4168 {
4169 if (gAgent.isTeen())
4170 {
4171 LLNotifications::instance().add(notificationID+"_KB", llsdBlock);
4172 return true;
4173 }
4174 else if (gAgent.prefersPG())
4175 {
4176 LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
4177 return true;
4178 }
4179 }
4180 else if (regionAccess == SIM_ACCESS_ADULT)
4181 {
4182 if (!gAgent.isAdult())
4183 {
4184 LLNotifications::instance().add(notificationID+"_KB", llsdBlock);
4185 return true;
4186 }
4187 else if (gAgent.prefersPG() || gAgent.prefersMature())
4188 {
4189 LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
4190 return true;
4191 }
4192 }
4193 return false;
4059} 4194}
4060 4195
4061void process_alert_core(const std::string& message, BOOL modal) 4196bool attempt_standard_notification(LLMessageSystem* msgsystem)
4197{
4198 // if we have additional alert data
4199 if (msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
4200 {
4201 // notification was specified using the new mechanism, so we can just handle it here
4202 std::string notificationID;
4203 std::string llsdRaw;
4204 LLSD llsdBlock;
4205 msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
4206 msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw);
4207 if (llsdRaw.length())
4208 {
4209 std::istringstream llsdData(llsdRaw);
4210 if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length()))
4211 {
4212 llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl;
4213 }
4214 }
4215
4216 if (
4217 (notificationID == "RegionEntryAccessBlocked") ||
4218 (notificationID == "LandClaimAccessBlocked") ||
4219 (notificationID == "LandBuyAccessBlocked")
4220 )
4221 {
4222 /*---------------------------------------------------------------------
4223 (Commented so a grep will find the notification strings, since
4224 we construct them on the fly; if you add additional notifications,
4225 please update the comment.)
4226
4227 Could throw any of the following notifications:
4228
4229 RegionEntryAccessBlocked
4230 RegionEntryAccessBlocked_Notify
4231 RegionEntryAccessBlocked_Change
4232 RegionEntryAccessBlocked_KB
4233 LandClaimAccessBlocked
4234 LandClaimAccessBlocked_Notify
4235 LandClaimAccessBlocked_Change
4236 LandClaimAccessBlocked_KB
4237 LandBuyAccessBlocked
4238 LandBuyAccessBlocked_Notify
4239 LandBuyAccessBlocked_Change
4240 LandBuyAccessBlocked_KB
4241
4242 -----------------------------------------------------------------------*/
4243 if (handle_special_notification(notificationID, llsdBlock))
4244 {
4245 return true;
4246 }
4247 }
4248
4249 LLNotifications::instance().add(notificationID, llsdBlock);
4250 return true;
4251 }
4252 return false;
4253}
4254
4255
4256void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
4062{ 4257{
4063 // make sure the cursor is back to the usual default since the 4258 // make sure the cursor is back to the usual default since the
4064 // alert is probably due to some kind of error. 4259 // alert is probably due to some kind of error.
4065 gViewerWindow->getWindow()->resetBusyCount(); 4260 gViewerWindow->getWindow()->resetBusyCount();
4261
4262 if (!attempt_standard_notification(msgsystem))
4263 {
4264 BOOL modal = FALSE;
4265 msgsystem->getBOOL("AlertData", "Modal", modal);
4266 std::string buffer;
4267 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
4268 process_alert_core(buffer, modal);
4269 }
4270}
4066 4271
4272// The only difference between this routine and the previous is the fact that
4273// for this routine, the modal parameter is always false. Sadly, for the message
4274// handled by this routine, there is no "Modal" parameter on the message, and
4275// there's no API to tell if a message has the given parameter or not.
4276// So we can't handle the messages with the same handler.
4277void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
4278{
4279 // make sure the cursor is back to the usual default since the
4280 // alert is probably due to some kind of error.
4281 gViewerWindow->getWindow()->resetBusyCount();
4282
4283 if (!attempt_standard_notification(msgsystem))
4284 {
4285 BOOL modal = FALSE;
4286 std::string buffer;
4287 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
4288 process_alert_core(buffer, modal);
4289 }
4290}
4291
4292void process_alert_core(const std::string& message, BOOL modal)
4293{
4067 // HACK -- handle callbacks for specific alerts 4294 // HACK -- handle callbacks for specific alerts
4068 if ( message == "You died and have been teleported to your home location") 4295 if ( message == "You died and have been teleported to your home location")
4069 { 4296 {
@@ -4085,54 +4312,54 @@ void process_alert_core(const std::string& message, BOOL modal)
4085 // Allow the server to spawn a named alert so that server alerts can be 4312 // Allow the server to spawn a named alert so that server alerts can be
4086 // translated out of English. 4313 // translated out of English.
4087 std::string alert_name(message.substr(ALERT_PREFIX.length())); 4314 std::string alert_name(message.substr(ALERT_PREFIX.length()));
4088 LLAlertDialog::showXml(alert_name); 4315 LLNotifications::instance().add(alert_name);
4089 } 4316 }
4090 else if (message.find(NOTIFY_PREFIX) == 0) 4317 else if (message.find(NOTIFY_PREFIX) == 0)
4091 { 4318 {
4092 // Allow the server to spawn a named notification so that server notifications can be 4319 // Allow the server to spawn a named notification so that server notifications can be
4093 // translated out of English. 4320 // translated out of English.
4094 std::string notify_name(message.substr(NOTIFY_PREFIX.length())); 4321 std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
4095 LLNotifyBox::showXml(notify_name); 4322 LLNotifications::instance().add(notify_name);
4096 } 4323 }
4097 else if (message[0] == '/') 4324 else if (message[0] == '/')
4098 { 4325 {
4099 // System message is important, show in upper-right box not tip 4326 // System message is important, show in upper-right box not tip
4100 std::string text(message.substr(1)); 4327 std::string text(message.substr(1));
4101 LLStringUtil::format_map_t args; 4328 LLSD args;
4102 if (text.substr(0,17) == "RESTART_X_MINUTES") 4329 if (text.substr(0,17) == "RESTART_X_MINUTES")
4103 { 4330 {
4104 S32 mins = 0; 4331 S32 mins = 0;
4105 LLStringUtil::convertToS32(text.substr(18), mins); 4332 LLStringUtil::convertToS32(text.substr(18), mins);
4106 args["[MINUTES]"] = llformat("%d",mins); 4333 args["MINUTES"] = llformat("%d",mins);
4107 LLNotifyBox::showXml("RegionRestartMinutes", args); 4334 LLNotifications::instance().add("RegionRestartMinutes", args);
4108 } 4335 }
4109 else if (text.substr(0,17) == "RESTART_X_SECONDS") 4336 else if (text.substr(0,17) == "RESTART_X_SECONDS")
4110 { 4337 {
4111 S32 secs = 0; 4338 S32 secs = 0;
4112 LLStringUtil::convertToS32(text.substr(18), secs); 4339 LLStringUtil::convertToS32(text.substr(18), secs);
4113 args["[SECONDS]"] = llformat("%d",secs); 4340 args["SECONDS"] = llformat("%d",secs);
4114 LLNotifyBox::showXml("RegionRestartSeconds", args); 4341 LLNotifications::instance().add("RegionRestartSeconds", args);
4115 } 4342 }
4116 else 4343 else
4117 { 4344 {
4118 // *TODO:translate 4345 // *TODO:translate
4119 args["[MESSAGE]"] = text; 4346 args["MESSAGE"] = text;
4120 LLNotifyBox::showXml("SystemMessage", args); 4347 LLNotifications::instance().add("SystemMessage", args);
4121 } 4348 }
4122 } 4349 }
4123 else if (modal) 4350 else if (modal)
4124 { 4351 {
4125 // *TODO:translate 4352 // *TODO:translate
4126 LLStringUtil::format_map_t args; 4353 LLSD args;
4127 args["[ERROR_MESSAGE]"] = message; 4354 args["ERROR_MESSAGE"] = message;
4128 gViewerWindow->alertXml("ErrorMessage", args); 4355 LLNotifications::instance().add("ErrorMessage", args);
4129 } 4356 }
4130 else 4357 else
4131 { 4358 {
4132 // *TODO:translate 4359 // *TODO:translate
4133 LLStringUtil::format_map_t args; 4360 LLSD args;
4134 args["[MESSAGE]"] = message; 4361 args["MESSAGE"] = message;
4135 LLNotifyBox::showXml("SystemMessageTip", args); 4362 LLNotifications::instance().add("SystemMessageTip", args);
4136 } 4363 }
4137} 4364}
4138 4365
@@ -4181,7 +4408,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
4181{ 4408{
4182 if (gAgent.inPrelude()) 4409 if (gAgent.inPrelude())
4183 { 4410 {
4184 // JC: In prelude, bumping is OK. This dialog is rather confusing to 4411 // In prelude, bumping is OK. This dialog is rather confusing to
4185 // newbies, so we don't show it. Drop the packet on the floor. 4412 // newbies, so we don't show it. Drop the packet on the floor.
4186 return; 4413 return;
4187 } 4414 }
@@ -4256,7 +4483,11 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
4256 LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance()); 4483 LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
4257 4484
4258 S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); 4485 S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
4486
4487 LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
4488
4259 LLFloaterImagePreview::setUploadAmount(upload_cost); 4489 LLFloaterImagePreview::setUploadAmount(upload_cost);
4490 LLFloaterAnimPreview::setUploadAmount(upload_cost);
4260 4491
4261 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost)); 4492 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
4262 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost)); 4493 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
@@ -4264,23 +4495,7 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
4264 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost)); 4495 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
4265} 4496}
4266 4497
4267class LLScriptQuestionCBData 4498void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
4268{
4269public:
4270 LLScriptQuestionCBData(const LLUUID &taskid, const LLUUID &itemid, const LLHost &sender, S32 questions, const std::string& object_name, const std::string& owner_name)
4271 : mTaskID(taskid), mItemID(itemid), mSender(sender), mQuestions(questions), mObjectName(object_name), mOwnerName(owner_name)
4272 {
4273 }
4274
4275 LLUUID mTaskID;
4276 LLUUID mItemID;
4277 LLHost mSender;
4278 S32 mQuestions;
4279 std::string mObjectName;
4280 std::string mOwnerName;
4281};
4282
4283void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_questions, BOOL granted)
4284{ 4499{
4285 // only continue if at least some permissions were requested 4500 // only continue if at least some permissions were requested
4286 if (orig_questions) 4501 if (orig_questions)
@@ -4291,16 +4506,16 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4291 // located in [REGIONNAME] at [REGIONPOS], 4506 // located in [REGIONNAME] at [REGIONPOS],
4292 // has been <granted|denied> permission to: [PERMISSIONS]." 4507 // has been <granted|denied> permission to: [PERMISSIONS]."
4293 4508
4294 LLUIString notice(LLNotifyBox::getTemplateMessage(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied")); 4509 LLUIString notice(LLFloaterChat::getInstance()->getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
4295 4510
4296 // always include the object name and owner name 4511 // always include the object name and owner name
4297 notice.setArg("[OBJECTNAME]", cbdata->mObjectName); 4512 notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
4298 notice.setArg("[OWNERNAME]", cbdata->mOwnerName); 4513 notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
4299 4514
4300 // try to lookup viewerobject that corresponds to the object that 4515 // try to lookup viewerobject that corresponds to the object that
4301 // requested permissions (here, taskid->requesting object id) 4516 // requested permissions (here, taskid->requesting object id)
4302 BOOL foundpos = FALSE; 4517 BOOL foundpos = FALSE;
4303 LLViewerObject* viewobj = gObjectList.findObject(cbdata->mTaskID); 4518 LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
4304 if (viewobj) 4519 if (viewobj)
4305 { 4520 {
4306 // found the viewerobject, get it's position in its region 4521 // found the viewerobject, get it's position in its region
@@ -4333,7 +4548,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4333 std::string perms; 4548 std::string perms;
4334 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) 4549 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
4335 { 4550 {
4336 if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i])) 4551 if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
4337 { 4552 {
4338 count++; 4553 count++;
4339 caution = TRUE; 4554 caution = TRUE;
@@ -4345,7 +4560,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4345 perms.append(", "); 4560 perms.append(", ");
4346 } 4561 }
4347 4562
4348 perms.append(LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i])); 4563 perms.append(LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]));
4349 } 4564 }
4350 } 4565 }
4351 4566
@@ -4361,43 +4576,12 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4361 } 4576 }
4362} 4577}
4363 4578
4364void script_question_decline_cb(S32 option, void* user_data) 4579bool script_question_cb(const LLSD& notification, const LLSD& response)
4365{ 4580{
4581 S32 option = LLNotification::getSelectedOption(notification, response);
4366 LLMessageSystem *msg = gMessageSystem; 4582 LLMessageSystem *msg = gMessageSystem;
4367 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data; 4583 S32 orig = notification["payload"]["questions"].asInteger();
4368 4584 S32 new_questions = orig;
4369 // remember the permissions requested so they can be checked
4370 // when it comes time to log a chat message
4371 S32 orig = cbdata->mQuestions;
4372
4373 // this callback will always decline all permissions requested
4374 // (any question flags set in the ScriptAnswerYes message
4375 // will be interpreted as having been granted, so clearing all
4376 // the bits will deny every permission)
4377 cbdata->mQuestions = 0;
4378
4379 // respond with the permissions denial
4380 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
4381 msg->nextBlockFast(_PREHASH_AgentData);
4382 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4383 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4384 msg->nextBlockFast(_PREHASH_Data);
4385 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
4386 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
4387 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
4388 msg->sendReliable(cbdata->mSender);
4389
4390 // log a chat message, if appropriate
4391 notify_cautioned_script_question(cbdata, orig, FALSE);
4392
4393 delete cbdata;
4394}
4395
4396void script_question_cb(S32 option, void* user_data)
4397{
4398 LLMessageSystem *msg = gMessageSystem;
4399 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
4400 S32 orig = cbdata->mQuestions;
4401 4585
4402 // check whether permissions were granted or denied 4586 // check whether permissions were granted or denied
4403 BOOL allowed = TRUE; 4587 BOOL allowed = TRUE;
@@ -4405,48 +4589,68 @@ void script_question_cb(S32 option, void* user_data)
4405 // if any other button was clicked, the permissions were denied 4589 // if any other button was clicked, the permissions were denied
4406 if (option != 0) 4590 if (option != 0)
4407 { 4591 {
4408 cbdata->mQuestions = 0; 4592 new_questions = 0;
4409 allowed = FALSE; 4593 allowed = FALSE;
4410 } 4594 }
4411 4595
4596 LLUUID task_id = notification["payload"]["task_id"].asUUID();
4597 LLUUID item_id = notification["payload"]["item_id"].asUUID();
4598
4412 // reply with the permissions granted or denied 4599 // reply with the permissions granted or denied
4413 msg->newMessageFast(_PREHASH_ScriptAnswerYes); 4600 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
4414 msg->nextBlockFast(_PREHASH_AgentData); 4601 msg->nextBlockFast(_PREHASH_AgentData);
4415 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 4602 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4416 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 4603 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4417 msg->nextBlockFast(_PREHASH_Data); 4604 msg->nextBlockFast(_PREHASH_Data);
4418 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID); 4605 msg->addUUIDFast(_PREHASH_TaskID, task_id);
4419 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID); 4606 msg->addUUIDFast(_PREHASH_ItemID, item_id);
4420 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions); 4607 msg->addS32Fast(_PREHASH_Questions, new_questions);
4421 msg->sendReliable(cbdata->mSender); 4608 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
4422 4609
4423 // only log a chat message if caution prompts are enabled 4610 // only log a chat message if caution prompts are enabled
4424 if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) 4611 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
4425 { 4612 {
4426 // log a chat message, if appropriate 4613 // log a chat message, if appropriate
4427 notify_cautioned_script_question(cbdata, orig, allowed); 4614 notify_cautioned_script_question(notification, response, orig, allowed);
4428 } 4615 }
4429 4616
4430 if ( option == 2 ) // mute 4617 if ( response["Mute"] ) // mute
4431 { 4618 {
4432 LLMuteList::getInstance()->add(LLMute(cbdata->mItemID, cbdata->mObjectName, LLMute::OBJECT)); 4619 LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
4433 4620
4434 // purge the message queue of any previously queued requests from the same source. DEV-4879 4621 // purge the message queue of any previously queued requests from the same source. DEV-4879
4435 class OfferMatcher : public LLNotifyBoxView::Matcher 4622 class OfferMatcher : public LLNotifyBoxView::Matcher
4436 { 4623 {
4437 public: 4624 public:
4438 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} 4625 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
4439 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const 4626 BOOL matches(const LLNotificationPtr notification) const
4440 { 4627 {
4441 return callback == script_question_cb && ((LLScriptQuestionCBData*)cb_data)->mItemID == blocked_id; 4628 if (notification->getName() == "ScriptQuestionCaution"
4629 || notification->getName() == "ScriptQuestion")
4630 {
4631 return (notification->getPayload()["item_id"].asUUID() == blocked_id);
4632 }
4633 return FALSE;
4442 } 4634 }
4443 private: 4635 private:
4444 const LLUUID& blocked_id; 4636 const LLUUID& blocked_id;
4445 }; 4637 };
4446 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(cbdata->mItemID)); 4638 // should do this via the channel
4639 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(item_id));
4447 } 4640 }
4448 delete cbdata; 4641
4642 if (response["Details"])
4643 {
4644 // respawn notification...
4645 LLNotifications::instance().add(notification["name"], notification["substitutions"], notification["payload"]);
4646
4647 // ...with description on top
4648 LLNotifications::instance().add("DebitPermissionDetails");
4649 }
4650 return false;
4449} 4651}
4652static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
4653static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
4450 4654
4451void process_script_question(LLMessageSystem *msg, void **user_data) 4655void process_script_question(LLMessageSystem *msg, void **user_data)
4452{ 4656{
@@ -4468,14 +4672,26 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4468 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name); 4672 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name);
4469 msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions ); 4673 msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
4470 4674
4471 // don't display permission requests if this object is muted - JS. 4675 // Special case. If the objects are owned by this agent, throttle per-object instead
4676 // of per-owner. It's common for residents to reset a ton of scripts that re-request
4677 // permissions, as with tier boxes. UUIDs can't be valid agent names and vice-versa,
4678 // so we'll reuse the same namespace for both throttle types.
4679 std::string throttle_name = owner_name;
4680 std::string self_name;
4681 gAgent.getName( self_name );
4682 if( owner_name == self_name )
4683 {
4684 throttle_name = taskid.getString();
4685 }
4686
4687 // don't display permission requests if this object is muted
4472 if (LLMuteList::getInstance()->isMuted(taskid)) return; 4688 if (LLMuteList::getInstance()->isMuted(taskid)) return;
4473 4689
4474 // throttle excessive requests from any specific user's scripts 4690 // throttle excessive requests from any specific user's scripts
4475 typedef LLKeyThrottle<std::string> LLStringThrottle; 4691 typedef LLKeyThrottle<std::string> LLStringThrottle;
4476 static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL ); 4692 static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
4477 4693
4478 switch (question_throttle.noteAction(owner_name)) 4694 switch (question_throttle.noteAction(throttle_name))
4479 { 4695 {
4480 case LLStringThrottle::THROTTLE_NEWLY_BLOCKED: 4696 case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
4481 LL_INFOS("Messaging") << "process_script_question throttled" 4697 LL_INFOS("Messaging") << "process_script_question throttled"
@@ -4496,9 +4712,9 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4496 { 4712 {
4497 BOOL caution = FALSE; 4713 BOOL caution = FALSE;
4498 S32 count = 0; 4714 S32 count = 0;
4499 LLStringUtil::format_map_t args; 4715 LLSD args;
4500 args["[OBJECTNAME]"] = object_name; 4716 args["OBJECTNAME"] = object_name;
4501 args["[NAME]"] = owner_name; 4717 args["NAME"] = owner_name;
4502 4718
4503 // check the received permission flags against each permission 4719 // check the received permission flags against each permission
4504 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) 4720 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
@@ -4506,34 +4722,32 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4506 if (questions & LSCRIPTRunTimePermissionBits[i]) 4722 if (questions & LSCRIPTRunTimePermissionBits[i])
4507 { 4723 {
4508 count++; 4724 count++;
4509 script_question += " " + LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]) + "\n"; 4725 script_question += " " + LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]) + "\n";
4510 4726
4511 // check whether permission question should cause special caution dialog 4727 // check whether permission question should cause special caution dialog
4512 caution |= LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]); 4728 caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
4513 } 4729 }
4514 } 4730 }
4515 args["[QUESTIONS]"] = script_question; 4731 args["QUESTIONS"] = script_question;
4516 4732
4517 LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name); 4733 LLSD payload;
4734 payload["task_id"] = taskid;
4735 payload["item_id"] = itemid;
4736 payload["sender"] = sender.getIPandPort();
4737 payload["questions"] = questions;
4738 payload["object_name"] = object_name;
4739 payload["owner_name"] = owner_name;
4518 4740
4519 // check whether cautions are even enabled or not 4741 // check whether cautions are even enabled or not
4520 if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) 4742 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
4521 { 4743 {
4522 if (caution) 4744 // display the caution permissions prompt
4523 { 4745 LLNotifications::instance().add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
4524 // display the caution permissions prompt
4525 LLNotifyBox::showXml("ScriptQuestionCaution", args, TRUE, script_question_cb, cbdata);
4526 }
4527 else
4528 {
4529 // display the permissions request normally
4530 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
4531 }
4532 } 4746 }
4533 else 4747 else
4534 { 4748 {
4535 // fall back to default behavior if cautions are entirely disabled 4749 // fall back to default behavior if cautions are entirely disabled
4536 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata); 4750 LLNotifications::instance().add("ScriptQuestion", args, payload);
4537 } 4751 }
4538 4752
4539 } 4753 }
@@ -4668,20 +4882,66 @@ std::string formatted_time(const time_t& the_time)
4668void process_teleport_failed(LLMessageSystem *msg, void**) 4882void process_teleport_failed(LLMessageSystem *msg, void**)
4669{ 4883{
4670 std::string reason; 4884 std::string reason;
4671 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); 4885 std::string big_reason;
4886 LLSD args;
4887
4888 // if we have additional alert data
4889 if (msg->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
4890 {
4891 // Get the message ID
4892 msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
4893 big_reason = LLAgent::sTeleportErrorMessages[reason];
4894 if ( big_reason.size() > 0 )
4895 { // Substitute verbose reason from the local map
4896 args["REASON"] = big_reason;
4897 }
4898 else
4899 { // Nothing found in the map - use what the server returned in the original message block
4900 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
4901 args["REASON"] = reason;
4902 }
4903
4904 LLSD llsd_block;
4905 std::string llsd_raw;
4906 msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw);
4907 if (llsd_raw.length())
4908 {
4909 std::istringstream llsd_data(llsd_raw);
4910 if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
4911 {
4912 llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl;
4913 }
4914 else
4915 {
4916 // change notification name in this special case
4917 if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
4918 {
4919 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
4920 {
4921 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
4922 }
4923 return;
4924 }
4925 }
4926 }
4672 4927
4673 LLStringUtil::format_map_t args;
4674 std::string big_reason = LLAgent::sTeleportErrorMessages[reason];
4675 if ( big_reason.size() > 0 )
4676 { // Substitute verbose reason from the local map
4677 args["[REASON]"] = big_reason;
4678 } 4928 }
4679 else 4929 else
4680 { // Nothing found in the map - use what the server returned 4930 {
4681 args["[REASON]"] = reason; 4931 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
4932
4933 big_reason = LLAgent::sTeleportErrorMessages[reason];
4934 if ( big_reason.size() > 0 )
4935 { // Substitute verbose reason from the local map
4936 args["REASON"] = big_reason;
4937 }
4938 else
4939 { // Nothing found in the map - use what the server returned
4940 args["REASON"] = reason;
4941 }
4682 } 4942 }
4683 4943
4684 gViewerWindow->alertXml("CouldNotTeleportReason", args); 4944 LLNotifications::instance().add("CouldNotTeleportReason", args);
4685 4945
4686 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) 4946 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
4687 { 4947 {
@@ -4803,9 +5063,10 @@ void send_group_notice(const LLUUID& group_id,
4803 bin_bucket_size); 5063 bin_bucket_size);
4804} 5064}
4805 5065
4806void handle_lure_callback(S32 option, const std::string& text, void* userdata) 5066bool handle_lure_callback(const LLSD& notification, const LLSD& response)
4807{ 5067{
4808 LLDynamicArray<LLUUID>* invitees = (LLDynamicArray<LLUUID>*)userdata; 5068 std::string text = response["message"].asString();
5069 S32 option = LLNotification::getSelectedOption(notification, response);
4809 5070
4810 if(0 == option) 5071 if(0 == option)
4811 { 5072 {
@@ -4817,21 +5078,17 @@ void handle_lure_callback(S32 option, const std::string& text, void* userdata)
4817 msg->nextBlockFast(_PREHASH_Info); 5078 msg->nextBlockFast(_PREHASH_Info);
4818 msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in. 5079 msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
4819 msg->addStringFast(_PREHASH_Message, text); 5080 msg->addStringFast(_PREHASH_Message, text);
4820 for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr) 5081 for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
5082 it != notification["payload"]["ids"].endArray();
5083 ++it)
4821 { 5084 {
4822 msg->nextBlockFast(_PREHASH_TargetData); 5085 msg->nextBlockFast(_PREHASH_TargetData);
4823 msg->addUUIDFast(_PREHASH_TargetID, *itr); 5086 msg->addUUIDFast(_PREHASH_TargetID, it->asUUID());
4824 } 5087 }
4825 gAgent.sendReliableMessage(); 5088 gAgent.sendReliableMessage();
4826 } 5089 }
4827 5090
4828 delete invitees; 5091 return false;
4829 invitees = NULL;
4830}
4831
4832void handle_lure_callback_godlike(S32 option, void* userdata)
4833{
4834 handle_lure_callback(option, LLStringUtil::null, userdata);
4835} 5092}
4836 5093
4837void handle_lure(const LLUUID& invitee) 5094void handle_lure(const LLUUID& invitee)
@@ -4844,21 +5101,23 @@ void handle_lure(const LLUUID& invitee)
4844// Prompt for a message to the invited user. 5101// Prompt for a message to the invited user.
4845void handle_lure(LLDynamicArray<LLUUID>& ids) 5102void handle_lure(LLDynamicArray<LLUUID>& ids)
4846{ 5103{
4847 LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids); 5104 LLSD edit_args;
5105 edit_args["REGION"] = gAgent.getRegion()->getName();
4848 5106
4849 LLStringUtil::format_map_t edit_args; 5107 LLSD payload;
4850 edit_args["[REGION]"] = gAgent.getRegion()->getName(); 5108 for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
5109 it != ids.end();
5110 ++it)
5111 {
5112 payload["ids"].append(*it);
5113 }
4851 if (gAgent.isGodlike()) 5114 if (gAgent.isGodlike())
4852 { 5115 {
4853 gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args, 5116 LLNotifications::instance().add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
4854 &handle_lure_callback_godlike, userdata,
4855 NULL, NULL, edit_args);
4856 } 5117 }
4857 else 5118 else
4858 { 5119 {
4859 gViewerWindow->alertXmlEditText("OfferTeleport", edit_args, 5120 LLNotifications::instance().add("OfferTeleport", edit_args, payload, handle_lure_callback);
4860 NULL, NULL,
4861 handle_lure_callback, userdata, edit_args);
4862 } 5121 }
4863} 5122}
4864 5123
@@ -4950,21 +5209,13 @@ const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
4950const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512; 5209const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
4951const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n"; 5210const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
4952 5211
4953struct ScriptDialogInfo 5212bool callback_script_dialog(const LLSD& notification, const LLSD& response)
4954{
4955 LLHost mSender;
4956 LLUUID mObjectID;
4957 S32 mChatChannel;
4958 std::vector<std::string> mButtons;
4959};
4960
4961void callback_script_dialog(S32 option, void* data)
4962{ 5213{
4963 ScriptDialogInfo* info = (ScriptDialogInfo*)data; 5214 LLNotificationForm form(notification["form"]);
4964 if (!info) return; 5215 std::string button = LLNotification::getSelectedOptionName(response);
4965 5216 S32 button_idx = LLNotification::getSelectedOption(notification, response);
4966 // Didn't click "Ignore" 5217 // Didn't click "Ignore"
4967 if (0 != option) 5218 if (button_idx != -1)
4968 { 5219 {
4969 LLMessageSystem* msg = gMessageSystem; 5220 LLMessageSystem* msg = gMessageSystem;
4970 msg->newMessage("ScriptDialogReply"); 5221 msg->newMessage("ScriptDialogReply");
@@ -4972,112 +5223,108 @@ void callback_script_dialog(S32 option, void* data)
4972 msg->addUUID("AgentID", gAgent.getID()); 5223 msg->addUUID("AgentID", gAgent.getID());
4973 msg->addUUID("SessionID", gAgent.getSessionID()); 5224 msg->addUUID("SessionID", gAgent.getSessionID());
4974 msg->nextBlock("Data"); 5225 msg->nextBlock("Data");
4975 msg->addUUID("ObjectID", info->mObjectID); 5226 msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
4976 msg->addS32("ChatChannel", info->mChatChannel); 5227 msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
4977 msg->addS32("ButtonIndex", option); 5228 msg->addS32("ButtonIndex", button_idx);
4978 msg->addString("ButtonLabel", info->mButtons[option-1]); 5229 msg->addString("ButtonLabel", button);
4979 msg->sendReliable(info->mSender); 5230 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
4980 } 5231 }
4981 5232
4982 delete info; 5233 return false;
4983} 5234}
5235static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
5236static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
4984 5237
4985void process_script_dialog(LLMessageSystem* msg, void**) 5238void process_script_dialog(LLMessageSystem* msg, void**)
4986{ 5239{
4987 S32 i; 5240 S32 i;
4988 5241
4989 ScriptDialogInfo* info = new ScriptDialogInfo; 5242 LLSD payload;
4990 5243
4991 std::string message; // Account for size of "Script Dialog:\n" 5244 std::string message;
4992 std::string first_name; 5245 std::string first_name;
4993 std::string last_name; 5246 std::string last_name;
4994 std::string title; 5247 std::string title;
4995 info->mSender = msg->getSender();
4996 5248
4997 msg->getUUID("Data", "ObjectID", info->mObjectID); 5249 LLUUID object_id;
5250 S32 chat_channel;
5251 msg->getUUID("Data", "ObjectID", object_id);
4998 msg->getString("Data", "FirstName", first_name); 5252 msg->getString("Data", "FirstName", first_name);
4999 msg->getString("Data", "LastName", last_name); 5253 msg->getString("Data", "LastName", last_name);
5000 msg->getString("Data", "ObjectName", title); 5254 msg->getString("Data", "ObjectName", title);
5001 msg->getString("Data", "Message", message); 5255 msg->getString("Data", "Message", message);
5002 msg->getS32("Data", "ChatChannel", info->mChatChannel); 5256 msg->getS32("Data", "ChatChannel", chat_channel);
5003 5257
5004 // unused for now 5258 // unused for now
5005 LLUUID image_id; 5259 LLUUID image_id;
5006 msg->getUUID("Data", "ImageID", image_id); 5260 msg->getUUID("Data", "ImageID", image_id);
5007 5261
5262 payload["sender"] = msg->getSender().getIPandPort();
5263 payload["object_id"] = object_id;
5264 payload["chat_channel"] = chat_channel;
5265
5266 // build up custom form
5008 S32 button_count = msg->getNumberOfBlocks("Buttons"); 5267 S32 button_count = msg->getNumberOfBlocks("Buttons");
5009 if (button_count > SCRIPT_DIALOG_MAX_BUTTONS) 5268 if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
5010 { 5269 {
5011 button_count = SCRIPT_DIALOG_MAX_BUTTONS; 5270 button_count = SCRIPT_DIALOG_MAX_BUTTONS;
5012 } 5271 }
5013 5272
5273 LLNotificationForm form;
5014 for (i = 0; i < button_count; i++) 5274 for (i = 0; i < button_count; i++)
5015 { 5275 {
5016 std::string tdesc; 5276 std::string tdesc;
5017 msg->getString("Buttons", "ButtonLabel", tdesc, i); 5277 msg->getString("Buttons", "ButtonLabel", tdesc, i);
5018 info->mButtons.push_back(tdesc); 5278 form.addElement("button", std::string(tdesc));
5019 } 5279 }
5020 5280
5021 LLStringUtil::format_map_t args; 5281 LLSD args;
5022 args["[TITLE]"] = title; 5282 args["TITLE"] = title;
5023 args["[MESSAGE]"] = message; 5283 args["MESSAGE"] = message;
5284 LLNotificationPtr notification;
5024 if (!first_name.empty()) 5285 if (!first_name.empty())
5025 { 5286 {
5026 args["[FIRST]"] = first_name; 5287 args["FIRST"] = first_name;
5027 args["[LAST]"] = last_name; 5288 args["LAST"] = last_name;
5028 LLNotifyBox::showXml("ScriptDialog", args, 5289 notification = LLNotifications::instance().add(
5029 callback_script_dialog, info, 5290 LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
5030 info->mButtons,
5031 TRUE);
5032 } 5291 }
5033 else 5292 else
5034 { 5293 {
5035 args["[GROUPNAME]"] = last_name; 5294 args["GROUPNAME"] = last_name;
5036 LLNotifyBox::showXml("ScriptDialogGroup", args, 5295 notification = LLNotifications::instance().add(
5037 callback_script_dialog, info, 5296 LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
5038 info->mButtons,
5039 TRUE);
5040 } 5297 }
5041} 5298}
5042 5299
5043//--------------------------------------------------------------------------- 5300//---------------------------------------------------------------------------
5044 5301
5045struct LoadUrlInfo
5046{
5047 LLUUID mObjectID;
5048 LLUUID mOwnerID;
5049 BOOL mOwnerIsGroup;
5050 std::string mObjectName;
5051 std::string mMessage;
5052 std::string mUrl;
5053};
5054 5302
5055std::vector<LoadUrlInfo*> gLoadUrlList; 5303std::vector<LLSD> gLoadUrlList;
5056 5304
5057void callback_load_url(S32 option, void* data) 5305bool callback_load_url(const LLSD& notification, const LLSD& response)
5058{ 5306{
5059 LoadUrlInfo* infop = (LoadUrlInfo*)data; 5307 S32 option = LLNotification::getSelectedOption(notification, response);
5060 if (!infop) return;
5061 5308
5062 if (0 == option) 5309 if (0 == option)
5063 { 5310 {
5064 LLWeb::loadURLExternal(infop->mUrl); 5311 LLWeb::loadURL(notification["payload"]["url"].asString());
5065 } 5312 }
5066 5313
5067 delete infop; 5314 return false;
5068 infop = NULL;
5069} 5315}
5316static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
5070 5317
5071 5318
5072// We've got the name of the person who owns the object hurling the url. 5319// We've got the name of the person who owns the object hurling the url.
5073// Display confirmation dialog. 5320// Display confirmation dialog.
5074void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) 5321void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
5075{ 5322{
5076 std::vector<LoadUrlInfo*>::iterator it; 5323 std::vector<LLSD>::iterator it;
5077 for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); ) 5324 for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
5078 { 5325 {
5079 LoadUrlInfo* infop = *it; 5326 LLSD load_url_info = *it;
5080 if (infop->mOwnerID == id) 5327 if (load_url_info["owner_id"].asUUID() == id)
5081 { 5328 {
5082 it = gLoadUrlList.erase(it); 5329 it = gLoadUrlList.erase(it);
5083 5330
@@ -5094,16 +5341,15 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
5094 // For legacy name-only mutes. 5341 // For legacy name-only mutes.
5095 if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name)) 5342 if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
5096 { 5343 {
5097 delete infop;
5098 infop = NULL;
5099 continue; 5344 continue;
5100 } 5345 }
5101 LLStringUtil::format_map_t args; 5346 LLSD args;
5102 args["[URL]"] = infop->mUrl; 5347 args["URL"] = load_url_info["url"].asString();
5103 args["[MESSAGE]"] = infop->mMessage; 5348 args["MESSAGE"] = load_url_info["message"].asString();;
5104 args["[OBJECTNAME]"] = infop->mObjectName; 5349 args["OBJECTNAME"] = load_url_info["object_name"].asString();
5105 args["[NAME]"] = owner_name; 5350 args["NAME"] = owner_name;
5106 LLNotifyBox::showXml("LoadWebPage", args, callback_load_url, infop); 5351
5352 LLNotifications::instance().add("LoadWebPage", args, load_url_info);
5107 } 5353 }
5108 else 5354 else
5109 { 5355 {
@@ -5114,40 +5360,51 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
5114 5360
5115void process_load_url(LLMessageSystem* msg, void**) 5361void process_load_url(LLMessageSystem* msg, void**)
5116{ 5362{
5117 LoadUrlInfo* infop = new LoadUrlInfo; 5363 LLUUID object_id;
5118 5364 LLUUID owner_id;
5119 msg->getString("Data", "ObjectName", infop->mObjectName); 5365 BOOL owner_is_group;
5120 msg->getUUID( "Data", "ObjectID", infop->mObjectID); 5366 char object_name[256]; /* Flawfinder: ignore */
5121 msg->getUUID( "Data", "OwnerID", infop->mOwnerID); 5367 char message[256]; /* Flawfinder: ignore */
5122 msg->getBOOL( "Data", "OwnerIsGroup", infop->mOwnerIsGroup); 5368 char url[256]; /* Flawfinder: ignore */
5123 msg->getString("Data", "Message", infop->mMessage); 5369
5124 msg->getString("Data", "URL", infop->mUrl); 5370 msg->getString("Data", "ObjectName", 256, object_name);
5371 msg->getUUID( "Data", "ObjectID", object_id);
5372 msg->getUUID( "Data", "OwnerID", owner_id);
5373 msg->getBOOL( "Data", "OwnerIsGroup", owner_is_group);
5374 msg->getString("Data", "Message", 256, message);
5375 msg->getString("Data", "URL", 256, url);
5376
5377 LLSD payload;
5378 payload["object_id"] = object_id;
5379 payload["owner_id"] = owner_id;
5380 payload["owner_is_group"] = owner_is_group;
5381 payload["object_name"] = object_name;
5382 payload["message"] = message;
5383 payload["url"] = url;
5125 5384
5126 // URL is safety checked in load_url above 5385 // URL is safety checked in load_url above
5127 5386
5128 // Check if object or owner is muted 5387 // Check if object or owner is muted
5129 if (LLMuteList::getInstance()->isMuted(infop->mObjectID, infop->mObjectName) || 5388 if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
5130 LLMuteList::getInstance()->isMuted(infop->mOwnerID)) 5389 LLMuteList::getInstance()->isMuted(owner_id))
5131 { 5390 {
5132 LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL; 5391 LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
5133 delete infop;
5134 infop = NULL;
5135 return; 5392 return;
5136 } 5393 }
5137 5394
5138 // Add to list of pending name lookups 5395 // Add to list of pending name lookups
5139 gLoadUrlList.push_back(infop); 5396 gLoadUrlList.push_back(payload);
5140 5397
5141 gCacheName->get(infop->mOwnerID, infop->mOwnerIsGroup, callback_load_url_name); 5398 gCacheName->get(owner_id, owner_is_group, callback_load_url_name);
5142} 5399}
5143 5400
5144 5401
5145void callback_download_complete(void** data, S32 result, LLExtStat ext_status) 5402void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
5146{ 5403{
5147 std::string* filepath = (std::string*)data; 5404 std::string* filepath = (std::string*)data;
5148 LLStringUtil::format_map_t args; 5405 LLSD args;
5149 args["[DOWNLOAD_PATH]"] = *filepath; 5406 args["DOWNLOAD_PATH"] = *filepath;
5150 gViewerWindow->alertXml("FinishedRawDownload", args); 5407 LLNotifications::instance().add("FinishedRawDownload", args);
5151 delete filepath; 5408 delete filepath;
5152} 5409}
5153 5410
@@ -5378,4 +5635,11 @@ void invalid_message_callback(LLMessageSystem* msg,
5378} 5635}
5379 5636
5380// Please do not add more message handlers here. This file is huge. 5637// Please do not add more message handlers here. This file is huge.
5381// Put them in a file related to the functionality you are implementing. JC 5638// Put them in a file related to the functionality you are implementing.
5639
5640void LLOfferInfo::forceResponse(InventoryOfferResponse response)
5641{
5642 LLNotification::Params params("UserGiveItem");
5643 params.functor(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
5644 LLNotifications::instance().forceResponse(params, response);
5645}