diff options
author | Jacek Antonelli | 2009-04-30 13:04:20 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-04-30 13:07:16 -0500 |
commit | ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch) | |
tree | 8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llviewermessage.cpp | |
parent | Second Life viewer sources 1.22.11 (diff) | |
download | meta-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.cpp | 1400 |
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 |
159 | void open_offer(const std::vector<LLUUID>& items, const std::string& from_name); | 159 | void open_offer(const std::vector<LLUUID>& items, const std::string& from_name); |
160 | void friendship_offer_callback(S32 option, void* user_data); | ||
161 | bool check_offer_throttle(const std::string& from_name, bool check_only); | 160 | bool check_offer_throttle(const std::string& from_name, bool check_only); |
162 | void callbackCacheEstateOwnerName(const LLUUID& id, | 161 | void 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 | ||
187 | struct LLFriendshipOffer | 186 | const 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 | ||
201 | bool 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 | } | ||
245 | static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback); | ||
246 | static 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 | ||
566 | struct LLJoinGroupData | 619 | bool 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 | |||
575 | void 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 | } |
698 | static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response); | ||
699 | static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response); | ||
700 | static 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. |
676 | class LLOpenTaskOffer : public LLInventoryAddedObserver | 725 | class LLOpenTaskOffer : public LLInventoryAddedObserver |
677 | { | 726 | { |
678 | protected: | 727 | protected: |
@@ -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 |
752 | bool check_offer_throttle(const std::string& from_name, bool check_only) | 801 | bool 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 | ||
943 | void inventory_offer_callback(S32 button, void* user_data) | 998 | LLOfferInfo::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 | |||
1013 | LLSD 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 | |||
1030 | bool 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 | ||
1254 | void group_vote_callback(S32 option, void *userdata) | 1347 | bool 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 | } |
1365 | static LLNotificationFunctorRegistration group_vote_callback_reg("GroupVote", group_vote_callback); | ||
1274 | 1366 | ||
1275 | struct LLLureInfo | 1367 | bool 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 | ||
1288 | void 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 | } |
1402 | static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback); | ||
1312 | 1403 | ||
1313 | void goto_url_callback(S32 option, void* user_data) | 1404 | bool 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 | } |
1414 | static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback); | ||
1322 | 1415 | ||
1323 | void process_improved_im(LLMessageSystem *msg, void **user_data) | 1416 | void 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 | ||
1992 | void friendship_offer_callback(S32 option, void* user_data) | 2131 | bool 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 | |||
2036 | struct LLCallingCardOfferData | ||
2037 | { | 2132 | { |
2038 | LLUUID mTransactionID; | 2133 | S32 option = LLNotification::getSelectedOption(notification, response); |
2039 | LLUUID mSourceID; | ||
2040 | LLHost mHost; | ||
2041 | }; | ||
2042 | |||
2043 | void 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 | } |
2170 | static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback); | ||
2084 | 2171 | ||
2085 | void process_offer_callingcard(LLMessageSystem* msg, void**) | 2172 | void 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 | ||
2140 | void process_accept_callingcard(LLMessageSystem* msg, void**) | 2221 | void process_accept_callingcard(LLMessageSystem* msg, void**) |
2141 | { | 2222 | { |
2142 | LLNotifyBox::showXml("CallingCardAccepted"); | 2223 | LLNotifications::instance().add("CallingCardAccepted"); |
2143 | } | 2224 | } |
2144 | 2225 | ||
2145 | void process_decline_callingcard(LLMessageSystem* msg, void**) | 2226 | void 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 | ||
2655 | static void display_release_notes(S32, void* data) | ||
2656 | { | ||
2657 | gAgent.getRegion()->showReleaseNotes(); | ||
2658 | } | ||
2659 | |||
2660 | void process_agent_movement_complete(LLMessageSystem* msg, void**) | 2736 | void 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 | ||
4044 | void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data) | 4142 | bool 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 | ||
4053 | void process_alert_message(LLMessageSystem *msgsystem, void **user_data) | 4158 | // some of the server notifications need special handling. This is where we do that. |
4159 | bool 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 | ||
4061 | void process_alert_core(const std::string& message, BOOL modal) | 4196 | bool 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 | |||
4256 | void 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. | ||
4277 | void 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 | |||
4292 | void 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 | ||
4267 | class LLScriptQuestionCBData | 4498 | void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted) |
4268 | { | ||
4269 | public: | ||
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 | |||
4283 | void 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 | ||
4364 | void script_question_decline_cb(S32 option, void* user_data) | 4579 | bool 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 | |||
4396 | void 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 | } |
4652 | static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb); | ||
4653 | static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb); | ||
4450 | 4654 | ||
4451 | void process_script_question(LLMessageSystem *msg, void **user_data) | 4655 | void 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) | |||
4668 | void process_teleport_failed(LLMessageSystem *msg, void**) | 4882 | void 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 | ||
4806 | void handle_lure_callback(S32 option, const std::string& text, void* userdata) | 5066 | bool 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 | |||
4832 | void handle_lure_callback_godlike(S32 option, void* userdata) | ||
4833 | { | ||
4834 | handle_lure_callback(option, LLStringUtil::null, userdata); | ||
4835 | } | 5092 | } |
4836 | 5093 | ||
4837 | void handle_lure(const LLUUID& invitee) | 5094 | void 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. |
4845 | void handle_lure(LLDynamicArray<LLUUID>& ids) | 5102 | void 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; | |||
4950 | const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512; | 5209 | const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512; |
4951 | const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n"; | 5210 | const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n"; |
4952 | 5211 | ||
4953 | struct ScriptDialogInfo | 5212 | bool 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 | |||
4961 | void 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 | } |
5235 | static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog); | ||
5236 | static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog); | ||
4984 | 5237 | ||
4985 | void process_script_dialog(LLMessageSystem* msg, void**) | 5238 | void 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 | ||
5045 | struct 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 | ||
5055 | std::vector<LoadUrlInfo*> gLoadUrlList; | 5303 | std::vector<LLSD> gLoadUrlList; |
5056 | 5304 | ||
5057 | void callback_load_url(S32 option, void* data) | 5305 | bool 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 | } |
5316 | static 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. |
5074 | void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) | 5321 | void 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 | ||
5115 | void process_load_url(LLMessageSystem* msg, void**) | 5361 | void 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 | ||
5145 | void callback_download_complete(void** data, S32 result, LLExtStat ext_status) | 5402 | void 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 | |||
5640 | void 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 | } | ||