summaryrefslogtreecommitdiff
path: root/indra/newview/llappearancemgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llappearancemgr.cpp')
-rw-r--r--indra/newview/llappearancemgr.cpp152
1 files changed, 114 insertions, 38 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 946d674e8b..71dec10e01 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -31,6 +31,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
+#include "llappearancelistener.h"
#include "llappearancemgr.h"
#include "llattachmentsmgr.h"
#include "llcommandhandler.h"
@@ -66,6 +67,8 @@
#include "llavatarpropertiesprocessor.h"
+LLAppearanceListener sAppearanceListener;
+
namespace
{
const S32 BAKE_RETRY_MAX_COUNT = 5;
@@ -537,9 +540,14 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
selfStopPhase("update_appearance_on_destroy");
- LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions,
- mEnforceOrdering,
- mPostUpdateFunc);
+ //avoid calling an update inside coroutine
+ bool force_restrictions(mEnforceItemRestrictions);
+ bool enforce_ordering(mEnforceOrdering);
+ nullary_func_t post_update_func(mPostUpdateFunc);
+ doOnIdleOneTime([force_restrictions,enforce_ordering,post_update_func]()
+ {
+ LLAppearanceMgr::instance().updateAppearanceFromCOF(force_restrictions, enforce_ordering, post_update_func);
+ });
}
}
@@ -848,7 +856,7 @@ void LLWearableHoldingPattern::checkMissingWearables()
// was requested but none was found, create a default asset as a replacement.
// In all other cases, don't do anything.
// For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud
- // due to logic in LLVOAvatarSelf::getIsCloud().
+ // due to logic in LLVOAvatarSelf::getHasMissingParts().
// For non-critical types (tatoo, socks, etc.) the wearable will just be missing.
(requested_by_type[type] > 0) &&
((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT)))
@@ -2037,7 +2045,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Moved from LLWearableList::ContextMenu for wider utility.
-bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
+bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids, bool warn_on_type_mismatch) const
{
// TODO: investigate wearables may not be loaded at this point EXT-8231
@@ -2067,7 +2075,10 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
}
else
{
+ if (warn_on_type_mismatch)
+ {
LL_WARNS() << "Unexpected wearable type" << LL_ENDL;
+ }
return false;
}
}
@@ -2258,7 +2269,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
}
if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
{
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents);
+ dump_sequential_xml(gAgentAvatarp->getDebugName() + "_slam_request", contents);
}
slam_inventory_folder(getCOF(), contents, link_waiter);
@@ -3951,7 +3962,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
{
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", result);
+ dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_ok", result);
}
} while (bRetry);
@@ -3960,7 +3971,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
/*static*/
void LLAppearanceMgr::debugAppearanceUpdateCOF(const LLSD& content)
{
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+ dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_error", content);
LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
<< " ================================= " << LL_ENDL;
@@ -4152,6 +4163,8 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, nul
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
+ auto attachment = gAgentAvatarp->getWornAttachment(id_to_remove);
+ if (attachment && attachment->isLocked()) continue;
const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
LLViewerInventoryItem *item = gInventory.getItem(linked_item_id);
if (item && item->getType() == LLAssetType::AT_OBJECT)
@@ -4717,48 +4730,69 @@ void wear_multiple(const uuid_vec_t& ids, bool replace)
LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, replace, cb);
}
-// SLapp for easy-wearing of a stock (library) avatar
-//
+bool wear_category(const LLSD& query_map, bool append)
+{
+ LLUUID folder_uuid;
+
+ if (query_map.has("folder_name"))
+ {
+ std::string outfit_folder_name = query_map["folder_name"];
+ folder_uuid = findDescendentCategoryIDByName(gInventory.getLibraryRootFolderID(), outfit_folder_name);
+ if (folder_uuid.isNull())
+ LL_WARNS() << "Couldn't find " << std::quoted(outfit_folder_name) << " in the Library" << LL_ENDL;
+ }
+ if (folder_uuid.isNull() && query_map.has("folder_id"))
+ {
+ folder_uuid = query_map["folder_id"].asUUID();
+ }
+
+ if (folder_uuid.notNull())
+ {
+ if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_uuid))
+ {
+ if (bool is_library = gInventory.isObjectDescendentOf(folder_uuid, gInventory.getRootFolderID()))
+ {
+ LLPointer<LLInventoryCategory> new_category = new LLInventoryCategory(folder_uuid, LLUUID::null, LLFolderType::FT_CLOTHING, "Quick Appearance");
+ LLAppearanceMgr::getInstance()->wearInventoryCategory(new_category, true, append);
+ }
+ else
+ {
+ LLAppearanceMgr::getInstance()->wearInventoryCategory(cat, true, append);
+ }
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "Couldn't find folder id" << folder_uuid << " in Inventory" << LL_ENDL;
+ }
+ }
+
+ return false;
+}
+
+bool LLAppearanceMgr::wearOutfit(const LLSD& query_map, bool append)
+{
+ return wear_category(query_map, append);
+}
+
class LLWearFolderHandler : public LLCommandHandler
{
public:
// not allowed from outside the app
- LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
+ LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) {}
bool handle(const LLSD& tokens,
const LLSD& query_map,
const std::string& grid,
LLMediaCtrl* web)
{
- LLSD::UUID folder_uuid;
-
- if (folder_uuid.isNull() && query_map.has("folder_name"))
+ if (wear_category(query_map, false))
{
- std::string outfit_folder_name = query_map["folder_name"];
- folder_uuid = findDescendentCategoryIDByName(
- gInventory.getLibraryRootFolderID(),
- outfit_folder_name);
- }
- if (folder_uuid.isNull() && query_map.has("folder_id"))
- {
- folder_uuid = query_map["folder_id"].asUUID();
- }
-
- if (folder_uuid.notNull())
- {
- LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
- LLUUID::null,
- LLFolderType::FT_CLOTHING,
- "Quick Appearance");
- if ( gInventory.getCategory( folder_uuid ) != NULL )
- {
- // Assume this is coming from the predefined avatars web floater
- LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
- LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
+ // Assume this is coming from the predefined avatars web floater
+ LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
- // *TODOw: This may not be necessary if initial outfit is chosen already -- josh
- gAgent.setOutfitChosen(true);
- }
+ // *TODOw: This may not be necessary if initial outfit is chosen already -- josh
+ gAgent.setOutfitChosen(true);
}
// release avatar picker keyboard focus
@@ -4768,4 +4802,46 @@ public:
}
};
+class LLAddFolderHandler : public LLCommandHandler
+{
+public:
+ // not allowed from outside the app
+ LLAddFolderHandler() : LLCommandHandler("add_folder", UNTRUSTED_BLOCK) {}
+
+ bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
+ {
+ wear_category(query_map, true);
+
+ return true;
+ }
+};
+
+class LLRemoveFolderHandler : public LLCommandHandler
+{
+public:
+ LLRemoveFolderHandler() : LLCommandHandler("remove_folder", UNTRUSTED_BLOCK) {}
+
+ bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
+ {
+ if (query_map.has("folder_id"))
+ {
+ LLUUID folder_id = query_map["folder_id"].asUUID();
+ if (folder_id.notNull())
+ {
+ if (LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id))
+ {
+ LLAppearanceMgr::instance().takeOffOutfit(cat->getLinkedUUID());
+ }
+ else
+ {
+ LL_WARNS() << "Couldn't find folder id" << folder_id << " in Inventory" << LL_ENDL;
+ }
+ }
+ }
+ return true;
+ }
+};
+
LLWearFolderHandler gWearFolderHandler;
+LLAddFolderHandler gAddFolderHandler;
+LLRemoveFolderHandler gRemoveFolderHandler;