summaryrefslogtreecommitdiff
path: root/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewermessage.cpp')
-rw-r--r--indra/newview/llviewermessage.cpp413
1 files changed, 250 insertions, 163 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 103989ee80..6435904fee 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -37,6 +37,7 @@
#include "lleconomy.h"
#include "lleventtimer.h"
#include "llfloaterreg.h"
+#include "llfolderview.h"
#include "llfollowcamparams.h"
#include "llinventorydefines.h"
#include "lllslconstants.h"
@@ -87,6 +88,7 @@
#include "lluri.h"
#include "llviewergenericmessage.h"
#include "llviewermenu.h"
+#include "llviewerinventory.h"
#include "llviewerjoystick.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
@@ -96,7 +98,6 @@
#include "llviewerwindow.h"
#include "llvlmanager.h"
#include "llvoavatarself.h"
-#include "llvotextbubble.h"
#include "llworld.h"
#include "pipeline.h"
#include "llfloaterworldmap.h"
@@ -122,6 +123,7 @@
//
const F32 BIRD_AUDIBLE_RADIUS = 32.0f;
const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;
+const F32 CAMERA_POSITION_THRESHOLD_SQUARED = 0.001f * 0.001f;
static const F32 LOGOUT_REPLY_TIME = 3.f; // Wait this long after LogoutReply before quitting.
// Determine how quickly residents' scripts can issue question dialogs
@@ -343,12 +345,11 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
{
LLViewerRegion *regionp = LLWorld::getInstance()->getRegion(mesgsys->getSender());
- if (!regionp || gNoRender)
+ if(!regionp)
{
+ llwarns << "Invalid region for layer data." << llendl;
return;
}
-
-
S32 size;
S8 type;
@@ -695,7 +696,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
return false;
}
-static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
+static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)
{
if (NULL == inventory_panel) return;
@@ -709,7 +710,7 @@ static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items,
continue;
}
- LLInventoryItem* item = gInventory.getItem(item_id);
+ LLInventoryObject* item = gInventory.getObject(item_id);
llassert(item);
if (!item) {
continue;
@@ -788,7 +789,6 @@ class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetO
public:
LLViewerInventoryMoveFromWorldObserver()
: LLInventoryAddItemByAssetObserver()
- , mActivePanel(NULL)
{
}
@@ -799,13 +799,16 @@ private:
/*virtual */void onAssetAdded(const LLUUID& asset_id)
{
// Store active Inventory panel.
- mActivePanel = LLInventoryPanel::getActiveInventoryPanel();
+ if (LLInventoryPanel::getActiveInventoryPanel())
+ {
+ mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
+ }
// Store selected items (without destination folder)
mSelectedItems.clear();
- if (mActivePanel)
+ if (LLInventoryPanel::getActiveInventoryPanel())
{
- mSelectedItems = mActivePanel->getRootFolder()->getSelectionList();
+ mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
}
mSelectedItems.erase(mMoveIntoFolderID);
}
@@ -816,12 +819,14 @@ private:
*/
void done()
{
+ LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
+
// if selection is not changed since watch started lets hightlight new items.
- if (mActivePanel && !isSelectionChanged())
+ if (active_panel && !isSelectionChanged())
{
LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL;
- mActivePanel->clearSelection();
- highlight_inventory_items_in_panel(mAddedItems, mActivePanel);
+ active_panel->clearSelection();
+ highlight_inventory_objects_in_panel(mAddedItems, active_panel);
}
}
@@ -829,16 +834,16 @@ private:
* Returns true if selected inventory items were changed since moved inventory items were started to watch.
*/
bool isSelectionChanged()
- {
- const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel();
+ {
+ LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
- if (NULL == mActivePanel || current_active_panel != mActivePanel)
+ if (NULL == active_panel)
{
return true;
}
// get selected items (without destination folder)
- selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList();
+ selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
selected_items.erase(mMoveIntoFolderID);
// compare stored & current sets of selected items
@@ -852,7 +857,7 @@ private:
return different_items.size() > 0;
}
- LLInventoryPanel *mActivePanel;
+ LLHandle<LLPanel> mActivePanel;
typedef std::set<LLUUID> selected_items_t;
selected_items_t mSelectedItems;
@@ -881,6 +886,75 @@ void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder
gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());
}
+
+/**
+ * Class to observe moving of items and to select them in inventory.
+ *
+ * Used currently for dragging from inbox to regular inventory folders
+ */
+
+class LLViewerInventoryMoveObserver : public LLInventoryObserver
+{
+public:
+
+ LLViewerInventoryMoveObserver(const LLUUID& object_id)
+ : LLInventoryObserver()
+ , mObjectID(object_id)
+ {
+ if (LLInventoryPanel::getActiveInventoryPanel())
+ {
+ mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle();
+ }
+ }
+
+ virtual ~LLViewerInventoryMoveObserver() {}
+ virtual void changed(U32 mask);
+
+private:
+ LLUUID mObjectID;
+ LLHandle<LLPanel> mActivePanel;
+
+};
+
+void LLViewerInventoryMoveObserver::changed(U32 mask)
+{
+ LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get());
+
+ if (NULL == active_panel)
+ {
+ gInventory.removeObserver(this);
+ return;
+ }
+
+ if((mask & (LLInventoryObserver::STRUCTURE)) != 0)
+ {
+ const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
+
+ std::set<LLUUID>::const_iterator id_it = changed_items.begin();
+ std::set<LLUUID>::const_iterator id_end = changed_items.end();
+ for (;id_it != id_end; ++id_it)
+ {
+ if ((*id_it) == mObjectID)
+ {
+ active_panel->clearSelection();
+ std::vector<LLUUID> items;
+ items.push_back(mObjectID);
+ highlight_inventory_objects_in_panel(items, active_panel);
+ active_panel->getRootFolder()->scrollToShowSelection();
+
+ gInventory.removeObserver(this);
+ break;
+ }
+ }
+ }
+}
+
+void set_dad_inbox_object(const LLUUID& object_id)
+{
+ LLViewerInventoryMoveObserver* move_observer = new LLViewerInventoryMoveObserver(object_id);
+ gInventory.addObserver(move_observer);
+}
+
//unlike the FetchObserver for AgentOffer, we only make one
//instance of the AddedObserver for TaskOffers
//and it never dies. We do this because we don't know the UUID of
@@ -937,7 +1011,6 @@ protected:
//one global instance to bind them
LLOpenTaskOffer* gNewInventoryObserver=NULL;
-
class LLNewInventoryHintObserver : public LLInventoryAddedObserver
{
protected:
@@ -947,6 +1020,8 @@ protected:
}
};
+LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL;
+
void start_new_inventory_observer()
{
if (!gNewInventoryObserver) //task offer observer
@@ -963,54 +1038,37 @@ void start_new_inventory_observer()
gInventory.addObserver(gInventoryMoveObserver);
}
- gInventory.addObserver(new LLNewInventoryHintObserver());
+ if (!gNewInventoryHintObserver)
+ {
+ // Observer is deleted by gInventory
+ gNewInventoryHintObserver = new LLNewInventoryHintObserver();
+ gInventory.addObserver(gNewInventoryHintObserver);
+ }
}
class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver
{
LOG_CLASS(LLDiscardAgentOffer);
+
public:
LLDiscardAgentOffer(const LLUUID& folder_id, const LLUUID& object_id) :
LLInventoryFetchItemsObserver(object_id),
mFolderID(folder_id),
mObjectID(object_id) {}
- virtual ~LLDiscardAgentOffer() {}
+
virtual void done()
{
LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL;
- const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- bool notify = false;
- if(trash_id.notNull() && mObjectID.notNull())
- {
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(mFolderID, -1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
- update.push_back(new_folder);
- gInventory.accountForUpdate(update);
- gInventory.moveObject(mObjectID, trash_id);
- LLInventoryObject* obj = gInventory.getObject(mObjectID);
- if(obj)
- {
- // no need to restamp since this is already a freshly
- // stamped item.
- obj->updateParentOnServer(FALSE);
- notify = true;
- }
- }
- else
- {
- LL_WARNS("Messaging") << "DiscardAgentOffer unable to find: "
- << (trash_id.isNull() ? "trash " : "")
- << (mObjectID.isNull() ? "object" : "") << LL_ENDL;
- }
+
+ // We're invoked from LLInventoryModel::notifyObservers().
+ // If we now try to remove the inventory item, it will cause a nested
+ // notifyObservers() call, which won't work.
+ // So defer moving the item to trash until viewer gets idle (in a moment).
+ LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeItem, &gInventory, mObjectID));
gInventory.removeObserver(this);
- if(notify)
- {
- gInventory.notifyObservers();
- }
delete this;
}
+
protected:
LLUUID mFolderID;
LLUUID mObjectID;
@@ -1199,7 +1257,6 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
// Highlight item
const BOOL auto_open =
gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false
- !(asset_type == LLAssetType::AT_CALLINGCARD) && // don't open if it's a calling card
!from_name.empty(); // don't open if it's not from anyone.
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
if(active_panel)
@@ -1242,29 +1299,12 @@ bool highlight_offered_object(const LLUUID& obj_id)
void inventory_offer_mute_callback(const LLUUID& blocked_id,
const std::string& full_name,
- bool is_group,
- boost::shared_ptr<LLNotificationResponderInterface> offer_ptr)
+ bool is_group)
{
- LLOfferInfo* offer = dynamic_cast<LLOfferInfo*>(offer_ptr.get());
-
- std::string from_name = full_name;
- LLMute::EType type;
- if (is_group)
- {
- type = LLMute::GROUP;
- }
- else if(offer && offer->mFromObject)
- {
- //we have to block object by name because blocked_id is an id of owner
- type = LLMute::BY_NAME;
- }
- else
- {
- type = LLMute::AGENT;
- }
+ // *NOTE: blocks owner if the offer came from an object
+ LLMute::EType mute_type = is_group ? LLMute::GROUP : LLMute::AGENT;
- // id should be null for BY_NAME mute, see LLMuteList::add for details
- LLMute mute(type == LLMute::BY_NAME ? LLUUID::null : blocked_id, from_name, type);
+ LLMute mute(blocked_id, full_name, mute_type);
if (LLMuteList::getInstance()->add(mute))
{
LLPanelBlockedList::showPanelAndSelect(blocked_id);
@@ -1278,6 +1318,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
bool matches(const LLNotificationPtr notification) const
{
if(notification->getName() == "ObjectGiveItem"
+ || notification->getName() == "OwnObjectGiveItem"
|| notification->getName() == "UserGiveItem")
{
return (notification->getPayload()["from_id"].asUUID() == blocked_id);
@@ -1416,7 +1457,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
LLChat chat;
std::string log_message;
S32 button = LLNotificationsUtil::getSelectedOption(notification, response);
-
+
LLInventoryObserver* opener = NULL;
LLViewerInventoryCategory* catp = NULL;
catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
@@ -1438,7 +1479,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
llassert(notification_ptr != NULL);
if (notification_ptr != NULL)
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
}
}
@@ -1448,7 +1489,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
from_string = chatHistory_string = mFromName;
- bool busy=FALSE;
+ bool busy = gAgent.getBusy();
switch(button)
{
@@ -1463,15 +1504,18 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// This is an offer from an agent. In this case, the back
// end has already copied the items into your inventory,
// so we can fetch it out of our inventory.
- LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string);
- open_agent_offer->startFetch();
- if(catp || (itemp && itemp->isFinished()))
+ if (gSavedSettings.getBOOL("ShowOfferedInventory"))
{
- open_agent_offer->done();
- }
- else
- {
- opener = open_agent_offer;
+ LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string);
+ open_agent_offer->startFetch();
+ if(catp || (itemp && itemp->isFinished()))
+ {
+ open_agent_offer->done();
+ }
+ else
+ {
+ opener = open_agent_offer;
+ }
}
}
break;
@@ -1500,13 +1544,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
LLSD args;
args["MESSAGE"] = log_message;
- LLNotificationsUtil::add("SystemMessage", args);
+ LLNotificationsUtil::add("SystemMessageTip", args);
}
break;
- case IOR_BUSY:
- //Busy falls through to decline. Says to make busy message.
- busy=TRUE;
case IOR_MUTE:
// MUTE falls through to decline
case IOR_DECLINE:
@@ -1583,7 +1624,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
llassert(notification_ptr != NULL);
if (notification_ptr != NULL)
{
- gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr()));
+ gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
}
}
@@ -1652,7 +1693,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
from_string = chatHistory_string = mFromName;
}
- bool busy=FALSE;
+ bool busy = gAgent.getBusy();
switch(button)
{
@@ -1674,7 +1715,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
LLSD args;
args["MESSAGE"] = log_message;
- LLNotificationsUtil::add("SystemMessage", args);
+ LLNotificationsUtil::add("SystemMessageTip", args);
}
// we will want to open this item when it comes back.
@@ -1698,9 +1739,6 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
} // end switch (mIM)
break;
- case IOR_BUSY:
- //Busy falls through to decline. Says to make busy message.
- busy=TRUE;
case IOR_MUTE:
// MUTE falls through to decline
case IOR_DECLINE:
@@ -1715,15 +1753,18 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
// send the message
msg->sendReliable(mHost);
+
+ if (gSavedSettings.getBOOL("LogInventoryDecline"))
{
LLStringUtil::format_map_t log_message_args;
log_message_args["DESC"] = mDesc;
log_message_args["NAME"] = mFromName;
log_message = LLTrans::getString("InvOfferDecline", log_message_args);
+
+ LLSD args;
+ args["MESSAGE"] = log_message;
+ LLNotificationsUtil::add("SystemMessageTip", args);
}
- LLSD args;
- args["MESSAGE"] = log_message;
- LLNotificationsUtil::add("SystemMessage", args);
if (busy && (!mFromGroup && !mFromObject))
{
@@ -1761,20 +1802,13 @@ void LLOfferInfo::initRespondFunctionMap()
if(mRespondFunctions.empty())
{
mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
+ mRespondFunctions["OwnObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
}
}
void inventory_offer_handler(LLOfferInfo* info)
{
- //Until throttling is implmented, busy mode should reject inventory instead of silently
- //accepting it. SEE SL-39554
- if (gAgent.getBusy())
- {
- info->forceResponse(IOR_BUSY);
- return;
- }
-
//If muted, don't even go through the messaging stuff. Just curtail the offer here.
if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
{
@@ -1856,7 +1890,7 @@ void inventory_offer_handler(LLOfferInfo* info)
std::string verb = "select?name=" + LLURI::escape(msg);
args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString();
- LLNotification::Params p("ObjectGiveItem");
+ LLNotification::Params p;
// Object -> Agent Inventory Offer
if (info->mFromObject)
@@ -1866,7 +1900,10 @@ void inventory_offer_handler(LLOfferInfo* info)
// Note: sets inventory_task_offer_callback as the callback
p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
info->mPersist = true;
- p.name = "ObjectGiveItem";
+
+ // Offers from your own objects need a special notification template.
+ p.name = info->mFromID == gAgentID ? "OwnObjectGiveItem" : "ObjectGiveItem";
+
// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, info->mFromGroup == TRUE);
}
@@ -2163,10 +2200,6 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
void process_improved_im(LLMessageSystem *msg, void **user_data)
{
- if (gNoRender)
- {
- return;
- }
LLUUID from_id;
BOOL from_group;
LLUUID to_id;
@@ -2212,7 +2245,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
name = clean_name_from_im(name, dialog);
BOOL is_busy = gAgent.getBusy();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
+ // object IMs contain sender object id in session_id (STORM-1209)
+ || dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id);
BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
BOOL is_owned_by_me = FALSE;
BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
@@ -2547,8 +2582,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0];
info->mType = (LLAssetType::EType) bucketp->asset_type;
info->mObjectID = bucketp->object_id;
+ info->mFromObject = FALSE;
}
- else
+ else // IM_TASK_INVENTORY_OFFERED
{
if (sizeof(S8) != binary_bucket_size)
{
@@ -2558,6 +2594,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
info->mType = (LLAssetType::EType) binary_bucket[0];
info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
}
info->mIM = dialog;
@@ -2566,14 +2603,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
- if (dialog == IM_TASK_INVENTORY_OFFERED)
- {
- info->mFromObject = TRUE;
- }
- else
- {
- info->mFromObject = FALSE;
- }
info->mFromName = name;
info->mDesc = message;
info->mHost = msg->getSender();
@@ -2588,6 +2617,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Same as closing window
info->forceResponse(IOR_DECLINE);
}
+ else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
+ {
+ // Until throttling is implemented, busy mode should reject inventory instead of silently
+ // accepting it. SEE SL-39554
+ info->forceResponse(IOR_DECLINE);
+ }
else
{
inventory_offer_handler(info);
@@ -2600,6 +2635,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();;
LLSD payload;
payload["from_id"] = from_id;
+ // Passing the "SESSION_NAME" to use it for IM notification logging
+ // in LLTipHandler::processNotification(). See STORM-941.
+ payload["SESSION_NAME"] = name;
LLNotificationsUtil::add("InventoryAccepted", args, payload);
break;
}
@@ -2799,7 +2837,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
LLVector3 pos, look_at;
U64 region_handle;
- U8 region_access = SIM_ACCESS_MIN;
+ U8 region_access;
std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
std::string region_access_str = LLStringUtil::null;
std::string region_access_icn = LLStringUtil::null;
@@ -3207,7 +3245,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
if (is_audible)
{
BOOL visible_in_chat_bubble = FALSE;
- std::string verb;
color.setVec(1.f,1.f,1.f,1.f);
msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
@@ -3256,18 +3293,19 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
}
else
{
+ chat.mText = "";
switch(chat.mChatType)
{
case CHAT_TYPE_WHISPER:
- verb = LLTrans::getString("whisper") + " ";
+ chat.mText = LLTrans::getString("whisper") + " ";
break;
case CHAT_TYPE_DEBUG_MSG:
case CHAT_TYPE_OWNER:
case CHAT_TYPE_NORMAL:
- verb = "";
+ case CHAT_TYPE_DIRECT:
break;
case CHAT_TYPE_SHOUT:
- verb = LLTrans::getString("shout") + " ";
+ chat.mText = LLTrans::getString("shout") + " ";
break;
case CHAT_TYPE_START:
case CHAT_TYPE_STOP:
@@ -3275,13 +3313,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
break;
default:
LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL;
- verb = "";
break;
}
-
- chat.mText = "";
- chat.mText += verb;
chat.mText += mesg;
}
@@ -3761,8 +3795,19 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
}
else
{
- // This is likely just the initial logging in phase.
+ // This is initial log-in or a region crossing
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
+
+ if(LLStartUp::getStartupState() < STATE_STARTED)
+ { // This is initial log-in, not a region crossing:
+ // Set the camera looking ahead of the AV so send_agent_update() below
+ // will report the correct location to the server.
+ LLVector3 look_at_point = look_at;
+ look_at_point = agent_pos + look_at_point.rotVec(gAgent.getQuat());
+
+ static LLVector3 up_direction(0.0f, 0.0f, 1.0f);
+ LLViewerCamera::getInstance()->lookAt(agent_pos, look_at_point, up_direction);
+ }
}
if ( LLTracker::isTracking(NULL) )
@@ -3944,7 +3989,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't
// trigger a control event.
U32 control_flags = gAgent.getControlFlags();
+
MASK key_mask = gKeyboard->currentMask(TRUE);
+
if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
{
control_flags &= ~( AGENT_CONTROL_LBUTTON_DOWN |
@@ -4213,15 +4260,8 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
// Display green bubble on kill
if ( gShowObjectUpdates )
{
- LLViewerObject* newobject;
- newobject = gObjectList.createObjectViewer(LL_PCODE_LEGACY_TEXT_BUBBLE, objectp->getRegion());
-
- LLVOTextBubble* bubble = (LLVOTextBubble*) newobject;
-
- bubble->mColor.setVec(0.f, 1.f, 0.f, 1.f);
- bubble->setScale( 2.0f * bubble->getScale() );
- bubble->setPositionGlobal(objectp->getPositionGlobal());
- gPipeline.addObject(bubble);
+ LLColor4 color(0.f,1.f,0.f,1.f);
+ gPipeline.addDebugBlip(objectp->getPositionAgent(), color);
}
// Do the kill
@@ -4258,12 +4298,11 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data)
LLWorld::getInstance()->setSpaceTimeUSec(space_time_usec);
- //LL_DEBUGS("Messaging") << "time_synch() - " << sun_direction << ", " << sun_ang_velocity
- // << ", " << phase << LL_ENDL;
+ LL_DEBUGS("Windlight Sync") << "Sun phase: " << phase << " rad = " << fmodf(phase / F_TWO_PI + 0.25, 1.f) * 24.f << " h" << LL_ENDL;
gSky.setSunPhase(phase);
gSky.setSunTargetDirection(sun_direction, sun_ang_velocity);
- if (!gNoRender && !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()))
+ if ( !(gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || gSky.getOverrideSun()) )
{
gSky.setSunDirection(sun_direction, sun_ang_velocity);
}
@@ -4318,6 +4357,12 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
return;
}
+ // Don't play sounds from gestures if they are not enabled.
+ if (object_id == owner_id && !gSavedSettings.getBOOL("EnableGestureSounds"))
+ {
+ return;
+ }
+
gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
}
@@ -4737,7 +4782,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
BOOL force_mouselook;
mesgsys->getBOOLFast(_PREHASH_SitTransform, _PREHASH_ForceMouselook, force_mouselook);
- if (isAgentAvatarValid() && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
+ if (isAgentAvatarValid() && dist_vec_squared(camera_eye, camera_at) > CAMERA_POSITION_THRESHOLD_SQUARED)
{
gAgentCamera.setSitCamera(sitObjectID, camera_eye, camera_at);
}
@@ -5357,6 +5402,12 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
{
// notification was specified using the new mechanism, so we can just handle it here
std::string notificationID;
+ msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+ if (!LLNotifications::getInstance()->templateExists(notificationID))
+ {
+ return false;
+ }
+
std::string llsdRaw;
LLSD llsdBlock;
msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
@@ -5513,10 +5564,19 @@ void process_alert_core(const std::string& message, BOOL modal)
}
else
{
- LLSD args;
- std::string new_msg =LLNotifications::instance().getGlobalString(message);
- args["MESSAGE"] = new_msg;
- LLNotificationsUtil::add("SystemMessageTip", args);
+ // Hack fix for EXP-623 (blame fix on RN :)) to avoid a sim deploy
+ const std::string AUTOPILOT_CANCELED_MSG("Autopilot canceled");
+ if (message.find(AUTOPILOT_CANCELED_MSG) == std::string::npos )
+ {
+ LLSD args;
+ std::string new_msg =LLNotifications::instance().getGlobalString(message);
+
+ std::string localized_msg;
+ bool is_message_localized = LLTrans::findString(localized_msg, new_msg);
+
+ args["MESSAGE"] = is_message_localized ? localized_msg : new_msg;
+ LLNotificationsUtil::add("SystemMessageTip", args);
+ }
}
}
@@ -5525,21 +5585,12 @@ time_t gLastDisplayedTime = 0;
void handle_show_mean_events(void *)
{
- if (gNoRender)
- {
- return;
- }
LLFloaterReg::showInstance("bumps");
//LLFloaterBump::showInstance();
}
void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
{
- if (gNoRender)
- {
- return;
- }
-
static const U32 max_collision_list_size = 20;
if (gMeanCollisionList.size() > max_collision_list_size)
{
@@ -6245,6 +6296,18 @@ void send_group_notice(const LLUUID& group_id,
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
{
+ static const unsigned OFFER_RECIPIENT_LIMIT = 250;
+ if(notification["payload"]["ids"].size() > OFFER_RECIPIENT_LIMIT)
+ {
+ // More than OFFER_RECIPIENT_LIMIT targets will overload the message
+ // producing an llerror.
+ LLSD args;
+ args["OFFERS"] = notification["payload"]["ids"].size();
+ args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT);
+ LLNotificationsUtil::add("TooManyTeleportOffers", args);
+ return false;
+ }
+
std::string text = response["message"].asString();
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
@@ -6435,8 +6498,24 @@ bool callback_script_dialog(const LLSD& notification, const LLSD& response)
rtn_text = LLNotification::getSelectedOptionName(response);
}
- // Didn't click "Ignore"
- if (button_idx != -1)
+ // Button -2 = Mute
+ // Button -1 = Ignore - no processing needed for this button
+ // Buttons 0 and above = dialog choices
+
+ if (-2 == button_idx)
+ {
+ std::string object_name = notification["payload"]["object_name"].asString();
+ LLUUID object_id = notification["payload"]["object_id"].asUUID();
+ LLMute mute(object_id, object_name, LLMute::OBJECT);
+ if (LLMuteList::getInstance()->add(mute))
+ {
+ // This call opens the sidebar, displays the block list, and highlights the newly blocked
+ // object in the list so the user can see that their block click has taken effect.
+ LLPanelBlockedList::showPanelAndSelect(object_id);
+ }
+ }
+
+ if (0 <= button_idx)
{
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("ScriptDialogReply");
@@ -6464,7 +6543,14 @@ void process_script_dialog(LLMessageSystem* msg, void**)
LLUUID object_id;
msg->getUUID("Data", "ObjectID", object_id);
- if (LLMuteList::getInstance()->isMuted(object_id))
+// For compability with OS grids first check for presence of extended packet before fetching data.
+ LLUUID owner_id;
+ if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0)
+ {
+ msg->getUUID("OwnerData", "OwnerID", owner_id);
+ }
+
+ if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id))
{
return;
}
@@ -6472,12 +6558,12 @@ void process_script_dialog(LLMessageSystem* msg, void**)
std::string message;
std::string first_name;
std::string last_name;
- std::string title;
+ std::string object_name;
S32 chat_channel;
msg->getString("Data", "FirstName", first_name);
msg->getString("Data", "LastName", last_name);
- msg->getString("Data", "ObjectName", title);
+ msg->getString("Data", "ObjectName", object_name);
msg->getString("Data", "Message", message);
msg->getS32("Data", "ChatChannel", chat_channel);
@@ -6488,6 +6574,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)
payload["sender"] = msg->getSender().getIPandPort();
payload["object_id"] = object_id;
payload["chat_channel"] = chat_channel;
+ payload["object_name"] = object_name;
// build up custom form
S32 button_count = msg->getNumberOfBlocks("Buttons");
@@ -6506,7 +6593,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)
}
LLSD args;
- args["TITLE"] = title;
+ args["TITLE"] = object_name;
args["MESSAGE"] = message;
LLNotificationPtr notification;
if (!first_name.empty())