aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llviewermessage.cpp520
1 files changed, 322 insertions, 198 deletions
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 5dab363..5eafd9d 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -145,8 +145,14 @@ extern BOOL gDebugClicks;
145extern void bad_network_handler(); 145extern void bad_network_handler();
146 146
147// function prototypes 147// function prototypes
148void open_offer(const std::vector<LLUUID>& items); 148void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
149void friendship_offer_callback(S32 option, void* user_data); 149void friendship_offer_callback(S32 option, void* user_data);
150bool check_offer_throttle(const std::string& from_name, bool check_only);
151
152//inventory offer throttle globals
153LLFrameTimer gThrottleTimer;
154const U32 OFFER_THROTTLE_MAX_COUNT=5; //number of items per time period
155const F32 OFFER_THROTTLE_TIME=10.f; //time period in seconds
150 156
151struct LLFriendshipOffer 157struct LLFriendshipOffer
152{ 158{
@@ -195,11 +201,6 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
195 } 201 }
196} 202}
197 203
198BOOL can_afford_transaction(S32 cost)
199{
200 return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost)));
201}
202
203void send_complete_agent_movement(const LLHost& sim_host) 204void send_complete_agent_movement(const LLHost& sim_host)
204{ 205{
205 LLMessageSystem* msg = gMessageSystem; 206 LLMessageSystem* msg = gMessageSystem;
@@ -275,11 +276,19 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
275 276
276 mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type); 277 mesgsys->getS8Fast(_PREHASH_LayerID, _PREHASH_Type, type);
277 size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data); 278 size = mesgsys->getSizeFast(_PREHASH_LayerData, _PREHASH_Data);
278 if(!size) 279 if (0 == size)
279 { 280 {
280 llwarns << "Layer data has zero size." << llendl; 281 llwarns << "Layer data has zero size." << llendl;
281 return; 282 return;
282 } 283 }
284 if (size < 0)
285 {
286 // getSizeFast() is probably trying to tell us about an error
287 llwarns << "getSizeFast() returned negative result: "
288 << size
289 << llendl;
290 return;
291 }
283 U8 *datap = new U8[size]; 292 U8 *datap = new U8[size];
284 mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size); 293 mesgsys->getBinaryDataFast(_PREHASH_LayerData, _PREHASH_Data, datap, size);
285 LLVLData *vl_datap = new LLVLData(regionp, type, datap, size); 294 LLVLData *vl_datap = new LLVLData(regionp, type, datap, size);
@@ -326,25 +335,29 @@ void export_complete()
326 while ((pos = strstr(pos+1, "<sl:image ")) != 0) 335 while ((pos = strstr(pos+1, "<sl:image ")) != 0)
327 { 336 {
328 char *pos_check = strstr(pos, "checksum=\""); 337 char *pos_check = strstr(pos, "checksum=\"");
329 char *pos_uuid = strstr(pos_check, "\">");
330 338
331 if (pos_check && pos_uuid) 339 if (pos_check)
332 { 340 {
333 char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */ 341 char *pos_uuid = strstr(pos_check, "\">");
334 memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */
335 image_uuid_str[UUID_STR_SIZE-1] = 0;
336 342
337 LLUUID image_uuid(image_uuid_str); 343 if (pos_uuid)
344 {
345 char image_uuid_str[UUID_STR_SIZE]; /* Flawfinder: ignore */
346 memcpy(image_uuid_str, pos_uuid+2, UUID_STR_SIZE-1); /* Flawfinder: ignore */
347 image_uuid_str[UUID_STR_SIZE-1] = 0;
348
349 LLUUID image_uuid(image_uuid_str);
338 350
339 llinfos << "Found UUID: " << image_uuid << llendl; 351 llinfos << "Found UUID: " << image_uuid << llendl;
340 352
341 std::map<LLUUID, LLString>::iterator itor = gImageChecksums.find(image_uuid); 353 std::map<LLUUID, LLString>::iterator itor = gImageChecksums.find(image_uuid);
342 if (itor != gImageChecksums.end()) 354 if (itor != gImageChecksums.end())
343 {
344 llinfos << "Replacing with checksum: " << itor->second << llendl;
345 if (itor->second.c_str() != NULL)
346 { 355 {
347 memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */ 356 llinfos << "Replacing with checksum: " << itor->second << llendl;
357 if (itor->second.c_str() != NULL)
358 {
359 memcpy(&pos_check[10], itor->second.c_str(), 32); /* Flawfinder: ignore */
360 }
348 } 361 }
349 } 362 }
350 } 363 }
@@ -354,7 +367,7 @@ void export_complete()
354 fwrite(buffer, 1, length, fXMLOut); 367 fwrite(buffer, 1, length, fXMLOut);
355 fclose(fXMLOut); 368 fclose(fXMLOut);
356 369
357 delete buffer; 370 delete [] buffer;
358} 371}
359 372
360 373
@@ -432,7 +445,7 @@ void exported_j2c_complete(const LLTSCode status, void *user_data)
432 char *end = strrchr(file_path, gDirUtilp->getDirDelimiter()[0]); 445 char *end = strrchr(file_path, gDirUtilp->getDirDelimiter()[0]);
433 end[0] = 0; 446 end[0] = 0;
434 LLString output_file = llformat("%s/image-%03d.tga", file_path, image_num);//filename; 447 LLString output_file = llformat("%s/image-%03d.tga", file_path, image_num);//filename;
435 delete file_path; 448 delete [] file_path;
436 //S32 name_len = output_file.length(); 449 //S32 name_len = output_file.length();
437 //strcpy(&output_file[name_len-3], "tga"); 450 //strcpy(&output_file[name_len-3], "tga");
438 FILE* fOut = LLFile::fopen(output_file.c_str(), "wb"); /* Flawfinder: ignore */ 451 FILE* fOut = LLFile::fopen(output_file.c_str(), "wb"); /* Flawfinder: ignore */
@@ -599,31 +612,44 @@ void join_group_callback(S32 option, void* user_data)
599class LLOpenAgentOffer : public LLInventoryFetchObserver 612class LLOpenAgentOffer : public LLInventoryFetchObserver
600{ 613{
601public: 614public:
602 LLOpenAgentOffer() {} 615 LLOpenAgentOffer(const std::string& from_name) : mFromName(from_name) {}
603 virtual ~LLOpenAgentOffer() {} 616 /*virtual*/ void done()
604
605 virtual void done()
606 { 617 {
607 open_offer(mComplete); 618 open_offer(mComplete, mFromName);
608 gInventory.removeObserver(this); 619 gInventory.removeObserver(this);
609 delete this; 620 delete this;
610 } 621 }
622private:
623 std::string mFromName;
611}; 624};
612 625
613class LLOpenTaskOffer : public LLInventoryExistenceObserver 626//unlike the FetchObserver for AgentOffer, we only make one
627//instance of the AddedObserver for TaskOffers
628//and it never dies. We do this because we don't know the UUID of
629//task offers until they are accepted, so we don't wouldn't
630//know what to watch for, so instead we just watch for all additions. -Gigs
631class LLOpenTaskOffer : public LLInventoryAddedObserver
614{ 632{
615public:
616 LLOpenTaskOffer() {}
617 virtual ~LLOpenTaskOffer() {}
618
619protected: 633protected:
620 virtual void done() 634 /*virtual*/ void done()
621 { 635 {
622 open_offer(mExist); 636 open_offer(mAdded, "");
623 gInventory.removeObserver(this); 637 mAdded.clear();
624 delete this;
625 } 638 }
626}; 639 };
640
641//one global instance to bind them
642LLOpenTaskOffer* gNewInventoryObserver=NULL;
643
644void start_new_inventory_observer()
645{
646 if (!gNewInventoryObserver) //task offer observer
647 {
648 // Observer is deleted by gInventory
649 gNewInventoryObserver = new LLOpenTaskOffer;
650 gInventory.addObserver(gNewInventoryObserver);
651 }
652}
627 653
628class LLDiscardAgentOffer : public LLInventoryFetchComboObserver 654class LLDiscardAgentOffer : public LLInventoryFetchComboObserver
629{ 655{
@@ -675,7 +701,71 @@ protected:
675}; 701};
676 702
677 703
678void open_offer(const std::vector<LLUUID>& items) 704//Returns TRUE if we are OK, FALSE if we are throttled
705//Set check_only true if you want to know the throttle status
706//without registering a hit -Gigs
707bool check_offer_throttle(const std::string& from_name, bool check_only)
708{
709 static U32 throttle_count;
710 static bool throttle_logged;
711 LLChat chat;
712 LLString log_message;
713
714 if (!gSavedSettings.getBOOL("ShowNewInventory"))
715 return false;
716
717 if (check_only)
718 {
719 return gThrottleTimer.hasExpired();
720 }
721
722 if(gThrottleTimer.checkExpirationAndReset(OFFER_THROTTLE_TIME))
723 {
724 //llinfos << "Throttle Expired" << llendl;
725 throttle_count=1;
726 throttle_logged=false;
727 return true;
728 }
729 else //has not expired
730 {
731 //llinfos << "Throttle Not Expired, Count: " << throttle_count << llendl;
732 // When downloading the initial inventory we get a lot of new items
733 // coming in and can't tell that from spam. JC
734 if (gStartupState >= STATE_STARTED
735 && throttle_count >= OFFER_THROTTLE_MAX_COUNT)
736 {
737 if (!throttle_logged)
738 {
739 // Use the name of the last item giver, who is probably the person
740 // spamming you. JC
741 std::ostringstream message;
742 message << gSecondLife;
743 if (!from_name.empty())
744 {
745 message << ": Items coming in too fast from " << from_name;
746 }
747 else
748 {
749 message << ": Items coming in too fast";
750 }
751 message << ", automatic preview disabled for "
752 << OFFER_THROTTLE_TIME << " seconds.";
753 chat.mText = message.str();
754 //this is kinda important, so actually put it on screen
755 LLFloaterChat::addChat(chat, FALSE, FALSE);
756 throttle_logged=true;
757 }
758 return false;
759 }
760 else
761 {
762 throttle_count++;
763 return true;
764 }
765 }
766}
767
768void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
679{ 769{
680 std::vector<LLUUID>::const_iterator it = items.begin(); 770 std::vector<LLUUID>::const_iterator it = items.begin();
681 std::vector<LLUUID>::const_iterator end = items.end(); 771 std::vector<LLUUID>::const_iterator end = items.end();
@@ -693,33 +783,66 @@ void open_offer(const std::vector<LLUUID>& items)
693 { 783 {
694 continue; 784 continue;
695 } 785 }
696 switch(item->getType()) 786 //if we are throttled, don't display them - Gigs
787 if (check_offer_throttle(from_name, false))
697 { 788 {
698 case LLAssetType::AT_NOTECARD: 789 // I'm not sure this is a good idea. JC
699 open_notecard(*it, LLString("Note: ") + item->getName(), TRUE, LLUUID::null, FALSE); 790 // bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
700 break; 791 bool show_keep_discard = true;
701 case LLAssetType::AT_LANDMARK: 792 switch(item->getType())
702 open_landmark(*it, LLString("Landmark: ") + item->getName(), TRUE, LLUUID::null, FALSE);
703 break;
704 case LLAssetType::AT_TEXTURE:
705 open_texture(*it, LLString("Texture: ") + item->getName(), TRUE, LLUUID::null, FALSE);
706 break;
707 default:
708 {
709 // Don't auto-open the inventory - just select it if we
710 // already have an active inventory.
711 LLInventoryView* view = LLInventoryView::getActiveInventory();
712 if(view)
713 { 793 {
714 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); 794 case LLAssetType::AT_NOTECARD:
715 LLFocusMgr::FocusLostCallback callback; 795 open_notecard(*it, LLString("Note: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
716 callback = gFocusMgr.getFocusCallback(); 796 break;
717 view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); 797 case LLAssetType::AT_LANDMARK:
718 gFocusMgr.setKeyboardFocus(focus_ctrl, callback); 798 open_landmark(*it, LLString("Landmark: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
799 break;
800 case LLAssetType::AT_TEXTURE:
801 open_texture(*it, LLString("Texture: ") + item->getName(), show_keep_discard, LLUUID::null, FALSE);
802 break;
803 default:
719 break; 804 break;
720 } 805 }
721 } 806 }
807 //highlight item, if it's not in the trash or lost+found
808
809 // Don't auto-open the inventory floater
810 LLInventoryView* view = LLInventoryView::getActiveInventory();
811 if(!view)
812 {
813 return;
814 }
815
816 //Trash Check
817 LLUUID trash_id;
818 trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
819 if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
820 {
821 return;
722 } 822 }
823 LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
824 //BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view);
825 BOOL user_is_away = gAwayTimer.getStarted();
826
827 // don't select lost and found items if the user is active
828 if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id)
829 && !user_is_away)
830 {
831 return;
832 }
833
834 //Not sure about this check. Could make it easy to miss incoming items. -Gigs
835 //don't dick with highlight while the user is working
836 //if(inventory_has_focus && !user_is_away)
837 // break;
838 //llinfos << "Highlighting" << item->getUUID() << llendl;
839 //highlight item
840
841 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
842 LLFocusMgr::FocusLostCallback callback;
843 callback = gFocusMgr.getFocusCallback();
844 view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
845 gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
723 } 846 }
724} 847}
725 848
@@ -807,11 +930,11 @@ void inventory_offer_callback(S32 option, void* user_data)
807 char group_name[MAX_STRING]; /* Flawfinder: ignore */ 930 char group_name[MAX_STRING]; /* Flawfinder: ignore */
808 if (gCacheName->getGroupName(info->mFromID, group_name)) 931 if (gCacheName->getGroupName(info->mFromID, group_name))
809 { 932 {
810 from_string = LLString("An object named ") + info->mFromName + " owned by the group '" + group_name + "'"; 933 from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'";
811 } 934 }
812 else 935 else
813 { 936 {
814 from_string = LLString("An object named ") + info->mFromName + " owned by an unknown group"; 937 from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown group";
815 } 938 }
816 } 939 }
817 else 940 else
@@ -820,11 +943,11 @@ void inventory_offer_callback(S32 option, void* user_data)
820 char last_name[MAX_STRING]; /* Flawfinder: ignore */ 943 char last_name[MAX_STRING]; /* Flawfinder: ignore */
821 if (gCacheName->getName(info->mFromID, first_name, last_name)) 944 if (gCacheName->getName(info->mFromID, first_name, last_name))
822 { 945 {
823 from_string = LLString("An object named ") + info->mFromName + " owned by " + first_name + " " + last_name; 946 from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name;
824 } 947 }
825 else 948 else
826 { 949 {
827 from_string = LLString("An object named ") + info->mFromName + " owned by an unknown user"; 950 from_string = LLString("An object named '") + info->mFromName + "' owned by an unknown user";
828 } 951 }
829 } 952 }
830 } 953 }
@@ -833,9 +956,11 @@ void inventory_offer_callback(S32 option, void* user_data)
833 from_string = info->mFromName; 956 from_string = info->mFromName;
834 } 957 }
835 958
959 bool busy=FALSE;
960
836 switch(option) 961 switch(option)
837 { 962 {
838 case 0: 963 case IOR_ACCEPT:
839 // ACCEPT. The math for the dialog works, because the accept 964 // ACCEPT. The math for the dialog works, because the accept
840 // for inventory_offered, task_inventory_offer or 965 // for inventory_offered, task_inventory_offer or
841 // group_notice_inventory is 1 greater than the offer integer value. 966 // group_notice_inventory is 1 greater than the offer integer value.
@@ -846,9 +971,15 @@ void inventory_offer_callback(S32 option, void* user_data)
846 sizeof(info->mFolderID.mData)); 971 sizeof(info->mFolderID.mData));
847 // send the message 972 // send the message
848 msg->sendReliable(info->mHost); 973 msg->sendReliable(info->mHost);
849 log_message = info->mFromName + " gave you " + info->mDesc + "."; 974
850 chat.mText = log_message; 975 //don't spam them if they are getting flooded
851 LLFloaterChat::addChatHistory(chat); 976 if (check_offer_throttle(info->mFromName, true))
977 {
978 log_message = info->mFromName + " gave you " + info->mDesc + ".";
979 chat.mText = log_message;
980 LLFloaterChat::addChatHistory(chat);
981 }
982
852 // we will want to open this item when it comes back. 983 // we will want to open this item when it comes back.
853 lldebugs << "Initializing an opener for tid: " << info->mTransactionID 984 lldebugs << "Initializing an opener for tid: " << info->mTransactionID
854 << llendl; 985 << llendl;
@@ -861,7 +992,7 @@ void inventory_offer_callback(S32 option, void* user_data)
861 // so we can fetch it out of our inventory. 992 // so we can fetch it out of our inventory.
862 LLInventoryFetchObserver::item_ref_t items; 993 LLInventoryFetchObserver::item_ref_t items;
863 items.push_back(info->mObjectID); 994 items.push_back(info->mObjectID);
864 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer; 995 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
865 open_agent_offer->fetchItems(items); 996 open_agent_offer->fetchItems(items);
866 if(catp || (itemp && itemp->isComplete())) 997 if(catp || (itemp && itemp->isComplete()))
867 { 998 {
@@ -877,22 +1008,10 @@ void inventory_offer_callback(S32 option, void* user_data)
877 case IM_GROUP_NOTICE: 1008 case IM_GROUP_NOTICE:
878 case IM_GROUP_NOTICE_REQUESTED: 1009 case IM_GROUP_NOTICE_REQUESTED:
879 { 1010 {
880 // This is an offer from a task or group. 1011 // This is an offer from a task or group.
881 // Because it would be easy 1012 // We don't use a new instance of an opener
882 // to write a task which would overload your inventory, we 1013 // We instead use the singular observer gOpenTaskOffer
883 // force the offer to stay in an instant message until 1014 // Since it already exists, we don't need to actually do anything
884 // accepted. Thus, we have to respond, and then wait for
885 // the update to come back before we open the item.
886 LLOpenTaskOffer* open_task_offer = new LLOpenTaskOffer;
887 open_task_offer->watchItem(info->mObjectID);
888 if(itemp && itemp->isComplete())
889 {
890 opener->changed(0x0);
891 }
892 else
893 {
894 opener = open_task_offer;
895 }
896 } 1015 }
897 break; 1016 break;
898 default: 1017 default:
@@ -901,9 +1020,12 @@ void inventory_offer_callback(S32 option, void* user_data)
901 } 1020 }
902 break; 1021 break;
903 1022
904 case 2: 1023 case IOR_BUSY:
1024 //Busy falls through to decline. Says to make busy message.
1025 busy=TRUE;
1026 case IOR_MUTE:
905 // MUTE falls through to decline 1027 // MUTE falls through to decline
906 case 1: 1028 case IOR_DECLINE:
907 // DECLINE. The math for the dialog works, because the decline 1029 // DECLINE. The math for the dialog works, because the decline
908 // for inventory_offered, task_inventory_offer or 1030 // for inventory_offered, task_inventory_offer or
909 // group_notice_inventory is 2 greater than the offer integer value. 1031 // group_notice_inventory is 2 greater than the offer integer value.
@@ -941,7 +1063,7 @@ void inventory_offer_callback(S32 option, void* user_data)
941 } 1063 }
942 1064
943 } 1065 }
944 if (!info->mFromGroup && !info->mFromObject) 1066 if (busy || (!info->mFromGroup && !info->mFromObject))
945 { 1067 {
946 busy_message(msg,info->mFromID); 1068 busy_message(msg,info->mFromID);
947 } 1069 }
@@ -964,88 +1086,73 @@ void inventory_offer_callback(S32 option, void* user_data)
964 1086
965void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) 1087void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
966{ 1088{
967 switch(info->mType) 1089
1090 //Until throttling is implmented, busy mode should reject inventory instead of silently
1091 //accepting it. SEE SL-39554
1092 if (gAgent.getBusy())
1093 {
1094 inventory_offer_callback(IOR_BUSY, info);
1095 return;
1096 }
1097
1098 //If muted, don't even go through the messaging stuff. Just curtail the offer here.
1099 if (gMuteListp->isMuted(info->mFromID, info->mFromName))
1100 {
1101 inventory_offer_callback(IOR_MUTE, info);
1102 return;
1103 }
1104
1105 if (gSavedSettings.getBOOL("ShowNewInventory")
1106 && (info->mType == LLAssetType::AT_NOTECARD
1107 || info->mType == LLAssetType::AT_LANDMARK
1108 || info->mType == LLAssetType::AT_TEXTURE))
968 { 1109 {
969 // For certain types, just accept the items into the inventory, 1110 // For certain types, just accept the items into the inventory,
970 // and we'll automatically open them on receipt. 1111 // and we'll automatically open them on receipt.
971 case LLAssetType::AT_NOTECARD: 1112 // 0 = accept button
972 case LLAssetType::AT_LANDMARK: 1113 inventory_offer_callback(IOR_ACCEPT, info);
973 case LLAssetType::AT_TEXTURE: 1114 return;
974 { 1115 }
975 // 0 = accept button 1116
976 inventory_offer_callback(0, info); 1117 LLString::format_map_t args;
977 //LLInventoryView::sOpenNextNewItem = TRUE; 1118 args["[OBJECTNAME]"] = info->mDesc;
978 } 1119 args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType);
979 break; 1120
980 1121 // Name cache callbacks don't store userdata, so can't save
981 case LLAssetType::AT_SOUND: 1122 // off the LLOfferInfo. Argh. JC
982 case LLAssetType::AT_CALLINGCARD: 1123 BOOL name_found = FALSE;
983 case LLAssetType::AT_SCRIPT: 1124 char first_name[MAX_STRING]; /* Flawfinder: ignore */
984 case LLAssetType::AT_CLOTHING: 1125 char last_name[MAX_STRING]; /* Flawfinder: ignore */
985 case LLAssetType::AT_OBJECT: 1126 if (info->mFromGroup)
986 case LLAssetType::AT_CATEGORY: 1127 {
987 case LLAssetType::AT_ROOT_CATEGORY: 1128 if (gCacheName->getGroupName(info->mFromID, first_name))
988 case LLAssetType::AT_LSL_TEXT: 1129 {
989 case LLAssetType::AT_LSL_BYTECODE: 1130 args["[FIRST]"] = first_name;
990 case LLAssetType::AT_TEXTURE_TGA: 1131 args["[LAST]"] = "";
991 case LLAssetType::AT_BODYPART: 1132 name_found = TRUE;
992 case LLAssetType::AT_TRASH: 1133 }
993 case LLAssetType::AT_SNAPSHOT_CATEGORY: 1134 }
994 case LLAssetType::AT_LOST_AND_FOUND: 1135 else
995 case LLAssetType::AT_ANIMATION: 1136 {
996 case LLAssetType::AT_GESTURE: 1137 if (gCacheName->getName(info->mFromID, first_name, last_name))
997 default: 1138 {
998 { 1139 args["[FIRST]"] = first_name;
999 LLString::format_map_t args; 1140 args["[LAST]"] = last_name;
1000 args["[OBJECTNAME]"] = info->mDesc; 1141 name_found = TRUE;
1001 args["[OBJECTTYPE]"] = LLAssetType::lookupHumanReadable(info->mType); 1142 }
1002 1143 }
1003 // Name cache callbacks don't store userdata, so can't save 1144 if (from_task)
1004 // off the LLOfferInfo. Argh. JC 1145 {
1005 BOOL name_found = FALSE; 1146 args["[OBJECTFROMNAME]"] = info->mFromName;
1006 char first_name[MAX_STRING]; /* Flawfinder: ignore */ 1147 LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser",
1007 char last_name[MAX_STRING]; /* Flawfinder: ignore */ 1148 args, &inventory_offer_callback, (void*)info);
1008 if (info->mFromGroup) 1149 }
1009 { 1150 else
1010 if (gCacheName->getGroupName(info->mFromID, first_name)) 1151 {
1011 { 1152 // XUI:translate -> [FIRST] [LAST]
1012 args["[FIRST]"] = first_name; 1153 args["[NAME]"] = info->mFromName;
1013 args["[LAST]"] = ""; 1154 LLNotifyBox::showXml("UserGiveItem", args,
1014 name_found = TRUE; 1155 &inventory_offer_callback, (void*)info);
1015 }
1016 }
1017 else
1018 {
1019 if (gCacheName->getName(info->mFromID, first_name, last_name))
1020 {
1021 args["[FIRST]"] = first_name;
1022 args["[LAST]"] = last_name;
1023 name_found = TRUE;
1024 }
1025 }
1026 if (from_task)
1027 {
1028 args["[OBJECTFROMNAME]"] = info->mFromName;
1029 if (name_found)
1030 {
1031 LLNotifyBox::showXml("ObjectGiveItem", args,
1032 &inventory_offer_callback, (void*)info);
1033 }
1034 else
1035 {
1036 LLNotifyBox::showXml("ObjectGiveItemUnknownUser", args,
1037 &inventory_offer_callback, (void*)info);
1038 }
1039 }
1040 else
1041 {
1042 // XUI:translate -> [FIRST] [LAST]
1043 args["[NAME]"] = info->mFromName;
1044 LLNotifyBox::showXml("UserGiveItem", args,
1045 &inventory_offer_callback, (void*)info);
1046 }
1047 break;
1048 }
1049 } 1156 }
1050} 1157}
1051 1158
@@ -1538,10 +1645,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1538 } 1645 }
1539 else 1646 else
1540 { 1647 {
1541 if (dialog == IM_TASK_INVENTORY_OFFERED) 1648 inventory_offer_handler(info, dialog == IM_TASK_INVENTORY_OFFERED);
1542 inventory_offer_handler(info, TRUE);
1543 else
1544 inventory_offer_handler(info, FALSE);
1545 } 1649 }
1546 } 1650 }
1547 break; 1651 break;
@@ -1760,6 +1864,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1760 1864
1761 case IM_GOTO_URL: 1865 case IM_GOTO_URL:
1762 { 1866 {
1867 if (binary_bucket_size <= 0)
1868 {
1869 llwarns << "bad binary_bucket_size: "
1870 << binary_bucket_size
1871 << " - aborting function." << llendl;
1872 return;
1873 }
1874
1763 char* url = new char[binary_bucket_size]; 1875 char* url = new char[binary_bucket_size];
1764 if (url == NULL) 1876 if (url == NULL)
1765 { 1877 {
@@ -1985,16 +2097,22 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
1985 { 2097 {
1986 // automatically decline offer 2098 // automatically decline offer
1987 callingcard_offer_callback(1, (void*)offerdata); 2099 callingcard_offer_callback(1, (void*)offerdata);
1988 return; 2100 offerdata = NULL; // pointer was freed by callback
2101 }
2102 else
2103 {
2104 LLNotifyBox::showXml("OfferCallingCard", args,
2105 &callingcard_offer_callback, (void*)offerdata);
2106 offerdata = NULL; // pointer ownership transferred
1989 } 2107 }
1990
1991 LLNotifyBox::showXml("OfferCallingCard", args,
1992 &callingcard_offer_callback, (void*)offerdata);
1993 } 2108 }
1994 else 2109 else
1995 { 2110 {
1996 llwarns << "Calling card offer from an unknown source." << llendl; 2111 llwarns << "Calling card offer from an unknown source." << llendl;
1997 } 2112 }
2113
2114 delete offerdata; // !=NULL if we didn't give ownership away
2115 offerdata = NULL;
1998} 2116}
1999 2117
2000void process_accept_callingcard(LLMessageSystem* msg, void**) 2118void process_accept_callingcard(LLMessageSystem* msg, void**)
@@ -3609,7 +3727,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
3609 if (object) 3727 if (object)
3610 { 3728 {
3611 LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation()); 3729 LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
3612 if (!use_autopilot || (avatar->mIsSitting && avatar->getRoot() == object->getRoot())) 3730 if (!use_autopilot || (avatar && avatar->mIsSitting && avatar->getRoot() == object->getRoot()))
3613 { 3731 {
3614 //we're already sitting on this object, so don't autopilot 3732 //we're already sitting on this object, so don't autopilot
3615 } 3733 }
@@ -5002,9 +5120,10 @@ void onCovenantLoadComplete(LLVFS *vfs,
5002 5120
5003 if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) ) 5121 if( (file_length > 19) && !strncmp( buffer, "Linden text version", 19 ) )
5004 { 5122 {
5005 LLViewerTextEditor* editor = new LLViewerTextEditor("temp", 5123 LLViewerTextEditor* editor =
5006 LLRect(0,0,0,0), 5124 new LLViewerTextEditor("temp",
5007 file_length+1); 5125 LLRect(0,0,0,0),
5126 file_length+1);
5008 if( !editor->importBuffer( buffer ) ) 5127 if( !editor->importBuffer( buffer ) )
5009 { 5128 {
5010 llwarns << "Problem importing estate covenant." << llendl; 5129 llwarns << "Problem importing estate covenant." << llendl;
@@ -5020,27 +5139,32 @@ void onCovenantLoadComplete(LLVFS *vfs,
5020 } 5139 }
5021 else 5140 else
5022 { 5141 {
5023 if( gViewerStats ) 5142 llwarns << "Problem importing estate covenant: Covenant file format error." << llendl;
5024 { 5143 covenant_text = "Problem importing estate covenant: Covenant file format error.";
5025 gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); 5144 }
5026 } 5145 }
5027 5146 else
5028 if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || 5147 {
5029 LL_ERR_FILE_EMPTY == status) 5148 if( gViewerStats )
5030 { 5149 {
5031 covenant_text = "Estate covenant notecard is missing from database."; 5150 gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
5032 }
5033 else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
5034 {
5035 covenant_text = "Insufficient permissions to view estate covenant.";
5036 }
5037 else
5038 {
5039 covenant_text = "Unable to load estate covenant at this time.";
5040 }
5041
5042 llwarns << "Problem loading notecard: " << status << llendl;
5043 } 5151 }
5152
5153 if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
5154 LL_ERR_FILE_EMPTY == status)
5155 {
5156 covenant_text = "Estate covenant notecard is missing from database.";
5157 }
5158 else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
5159 {
5160 covenant_text = "Insufficient permissions to view estate covenant.";
5161 }
5162 else
5163 {
5164 covenant_text = "Unable to load estate covenant at this time.";
5165 }
5166
5167 llwarns << "Problem loading notecard: " << status << llendl;
5044 } 5168 }
5045 LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid); 5169 LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid);
5046 LLPanelLandCovenant::updateCovenantText(covenant_text); 5170 LLPanelLandCovenant::updateCovenantText(covenant_text);