Merged with default tip (Revision 07528d0f9440)

--HG--
branch : Appearance-Misc
master
Kitty Barnett 2018-03-29 11:08:54 +02:00
commit fb2e70a5b9
32 changed files with 804 additions and 228 deletions

View File

@ -0,0 +1 @@
54e81f61aca5bf7c655fb4bf94553aaca0251e43

View File

@ -0,0 +1,23 @@
[Appearance/Misc]
- fixed : LLAppearanceMgr::filterWearableItems() doesn't properly filter body parts
- fixed : LLWearableList::processGetAssetReply() creates multiple LLWearable instances for the same asset UUID
-> fix for http://jira.secondlife.com/browse/VWR-20608
- fixed : attachments sometimes detach only to instantly get reattached after logon
- fixed : Add to/Replace Outfit removes newly worn attachments on completion
-> fix for http://jira.secondlife.com/browse/VWR-18512
- fixed : "Replace Outfit" isn't available for non-outfit folders that don't contain a full set of body parts (eyes, hair base, skin and shape)
-> fix for http://jira.secondlife.com/browse/VWR-23972
- fixed : attachments that attach and then instantly detach don't have their COF link removed
- fixed : multiple LLWearableHoldingPattern instances lead to "COF corruption"
- fixed : get_is_item_worn() shouldn't make the assumption that items in COFs are always worn
- fixed : drag-and-drop wear behaviour of an attachment onto self isn't consistant with the drag-and-drop behaviour of wearables
-> normal-drop : replace wear
-> Ctrl-drop : add wear
- fixed : LLAppearanceMgr::registerAttachment() fails to (re)add a link for worn attachments that aren't linked to in COF at log-on
- fixed : LLViewerObject::getAttachmentItemID() sometimes returns the NULL UUID for the avatar's own attachments
- fixed : LLAppearanceMgr::updateAppearanceFromCOF() doesn't properly filter items collected from folder links
-> create an outfit with a folder link + "Replace Outfit" == wearables that exist in both COF and the linked folder will end up worn multiple times
- changed : enable "Replace Current Outfit" on the base outfit if it's marked dirty
- changed : "RenderUnloadedAvatar" no longer affects the user's own avatar
-> side-effect of the fix above due to the change to LLVOAvatar::isFullyLoaded()
- added : InitialWearablesLoadedSignal signal which is emitted *once* when the initial wearables are loaded

View File

@ -1,4 +1,5 @@
# -*- cmake -*-
include(FindWindowsSDK)
if (WINDOWS)
include(FindWindowsSDK)

View File

@ -92,7 +92,10 @@ LLWearableDictionary::LLWearableDictionary()
addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-05-29 (Catznip-2.6)
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE));
// [/SL:KB]
// addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));

View File

@ -159,6 +159,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>AISCommandFilterMask</key>
<map>
<key>Comment</key>
<string>AIS command filter (death by Kitty if you change this)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>65247</integer>
</map>
<key>AlertedUnsupportedHardware</key>
<map>
<key>Comment</key>

View File

@ -57,6 +57,9 @@
LLAgentWearables gAgentWearables;
BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
bool LLAgentWearables::mInitialWearablesLoaded = false;
// [/SL:KB]
using namespace LLAvatarAppearanceDefines;
@ -1134,6 +1137,13 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-09-22 (Catznip-2.2)
if (!mInitialWearablesLoaded)
{
mInitialWearablesLoaded = true;
mInitialWearablesLoadedSignal();
}
// [/SL:KB]
notifyLoadingFinished();
// Copy wearable params to avatar.
@ -1635,6 +1645,13 @@ bool LLAgentWearables::changeInProgress() const
return mCOFChangeInProgress;
}
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(const loaded_callback_t& cb)
{
return mInitialWearablesLoadedSignal.connect(cb);
}
// [/SL:KB]
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;

View File

@ -72,6 +72,9 @@ public:
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
BOOL areWearablesLoaded() const;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
bool areInitalWearablesLoaded() const { return mInitialWearablesLoaded; }
// [/SL:KB]
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
F32 getCOFChangeTime() const { return mCOFChangeTimer.getElapsedTimeF32(); }
void updateWearablesLoaded();
@ -199,6 +202,9 @@ public:
typedef boost::function<void()> loaded_callback_t;
typedef boost::signals2::signal<void()> loaded_signal_t;
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
boost::signals2::connection addInitialWearablesLoadedCallback(const loaded_callback_t& cb);
// [/SL:KB]
bool changeInProgress() const;
void notifyLoadingStarted();
@ -207,12 +213,18 @@ public:
private:
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
loaded_signal_t mInitialWearablesLoadedSignal; // emitted once when the initial wearables are loaded
// [/SL:KB]
//--------------------------------------------------------------------
// Member variables
//--------------------------------------------------------------------
private:
static BOOL mInitialWearablesUpdateReceived;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.2)
static bool mInitialWearablesLoaded;
// [/SL:KB]
BOOL mWearablesLoaded;
/**

View File

@ -436,14 +436,39 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
if (callback && !callback.empty())
{
LLUUID id(LLUUID::null);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
uuid_list_t ids;
switch (type)
{
case COPYLIBRARYCATEGORY:
if (result.has("category_id"))
{
ids.insert(result["category_id"]);
}
break;
case COPYINVENTORY:
{
AISUpdate::parseUUIDArray(result, "_created_items", ids);
AISUpdate::parseUUIDArray(result, "_created_categories", ids);
}
break;
default:
break;
}
if (result.has("category_id") && (type == COPYLIBRARYCATEGORY))
{
id = result["category_id"];
}
callback(id);
// If we were feeling daring we'd call LLInventoryCallback::fire for every item but it would take additional work to investigate whether all LLInventoryCallback derived classes
// were designed to handle multiple fire calls (with legacy link creation only one would ever fire per link creation) so we'll be cautious and only call for the first one for now
// (note that the LL code as written below will always call fire once with the NULL UUID for anything but CopyLibraryCategoryCommand so even the above is an improvement)
callback( (!ids.empty()) ? *ids.begin() : LLUUID::null);
// [/SL:KB]
// LLUUID id(LLUUID::null);
//
// if (result.has("category_id") && (type == COPYLIBRARYCATEGORY))
// {
// id = result["category_id"];
// }
//
// callback(id);
}
}

View File

@ -89,7 +89,10 @@ public:
void parseUpdate(const LLSD& update);
void parseMeta(const LLSD& update);
void parseContent(const LLSD& update);
void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
static void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
// [/SL:KB]
// void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
void parseLink(const LLSD& link_map);
void parseItem(const LLSD& link_map);
void parseCategory(const LLSD& link_map);

View File

@ -634,16 +634,20 @@ public:
bool pollMissingWearables();
bool isMissingCompleted();
void recoverMissingWearable(LLWearableType::EType type);
void clearCOFLinksForMissingWearables();
// void clearCOFLinksForMissingWearables();
void onWearableAssetFetch(LLViewerWearable *wearable);
void onAllComplete();
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
bool pollStopped();
// [/SL:KB]
typedef std::list<LLFoundData> found_list_t;
found_list_t& getFoundList();
void eraseTypeToLink(LLWearableType::EType type);
void eraseTypeToRecover(LLWearableType::EType type);
void setObjItems(const LLInventoryModel::item_array_t& items);
// void setObjItems(const LLInventoryModel::item_array_t& items);
void setGestItems(const LLInventoryModel::item_array_t& items);
bool isMostRecent();
void handleLateArrivals();
@ -653,7 +657,7 @@ public:
private:
found_list_t mFoundList;
LLInventoryModel::item_array_t mObjItems;
// LLInventoryModel::item_array_t mObjItems;
LLInventoryModel::item_array_t mGestItems;
typedef std::set<S32> type_set_t;
type_set_t mTypesToRecover;
@ -730,10 +734,11 @@ void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
mTypesToRecover.erase(type);
}
void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
{
mObjItems = items;
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
//void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
//{
// mObjItems = items;
//}
void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
{
@ -840,52 +845,52 @@ void LLWearableHoldingPattern::onAllComplete()
if (isAgentAvatarValid())
{
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
LLAgentWearables::llvo_vec_t objects_to_remove;
LLAgentWearables::llvo_vec_t objects_to_retain;
LLInventoryModel::item_array_t items_to_add;
LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
objects_to_remove,
objects_to_retain,
items_to_add);
LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
<< " attachments" << LL_ENDL;
// Here we remove the attachment pos overrides for *all*
// attachments, even those that are not being removed. This is
// needed to get joint positions all slammed down to their
// pre-attachment states.
gAgentAvatarp->clearAttachmentOverrides();
if (objects_to_remove.size() || items_to_add.size())
{
LL_DEBUGS("Avatar") << "ATT will remove " << objects_to_remove.size()
<< " and add " << items_to_add.size() << " items" << LL_ENDL;
}
// Take off the attachments that will no longer be in the outfit.
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
// LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
// LLAgentWearables::llvo_vec_t objects_to_remove;
// LLAgentWearables::llvo_vec_t objects_to_retain;
// LLInventoryModel::item_array_t items_to_add;
//
// LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
// objects_to_remove,
// objects_to_retain,
// items_to_add);
//
// LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
// << " attachments" << LL_ENDL;
//
// // Here we remove the attachment pos overrides for *all*
// // attachments, even those that are not being removed. This is
// // needed to get joint positions all slammed down to their
// // pre-attachment states.
// gAgentAvatarp->clearAttachmentOverrides();
//
// if (objects_to_remove.size() || items_to_add.size())
// {
// LL_DEBUGS("Avatar") << "ATT will remove " << objects_to_remove.size()
// << " and add " << items_to_add.size() << " items" << LL_ENDL;
// }
//
// // Take off the attachments that will no longer be in the outfit.
// LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
// Update wearables.
LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with "
<< mResolved << " wearable items " << LL_ENDL;
LLAppearanceMgr::instance().updateAgentWearables(this);
// Restore attachment pos overrides for the attachments that
// are remaining in the outfit.
for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
it != objects_to_retain.end();
++it)
{
LLViewerObject *objectp = *it;
gAgentAvatarp->addAttachmentOverridesForObject(objectp);
}
// Add new attachments to match those requested.
LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
LLAgentWearables::userAttachMultipleAttachments(items_to_add);
// // Restore attachment pos overrides for the attachments that
// // are remaining in the outfit.
// for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
// it != objects_to_retain.end();
// ++it)
// {
// LLViewerObject *objectp = *it;
// gAgentAvatarp->addAttachmentOverridesForObject(objectp);
// }
//
// // Add new attachments to match those requested.
// LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
// LLAgentWearables::userAttachMultipleAttachments(items_to_add);
}
if (isFetchCompleted() && isMissingCompleted())
@ -923,6 +928,12 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
{
// runway skip here?
LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
return true;
// [/SL:KB]
}
bool completed = isFetchCompleted();
@ -993,6 +1004,11 @@ void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLView
{
// runway skip here?
LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
return;
// [/SL:KB]
}
LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
@ -1044,19 +1060,32 @@ bool LLWearableHoldingPattern::isMissingCompleted()
return mTypesToLink.size()==0 && mTypesToRecover.size()==0;
}
void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
//void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
//{
// for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
// {
// LLFoundData &data = *it;
// if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
// {
// // Wearable link that was never resolved; remove links to it from COF
// LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
// LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
// }
// }
//}
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
bool LLWearableHoldingPattern::pollStopped()
{
for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
// We have to keep on polling until we're sure that all callbacks have completed or they'll cause a crash
if ( (isFetchCompleted()) && (isMissingCompleted()) )
{
LLFoundData &data = *it;
if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
{
// Wearable link that was never resolved; remove links to it from COF
LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
}
delete this;
return true;
}
return false;
}
// [/SL:KB]
bool LLWearableHoldingPattern::pollMissingWearables()
{
@ -1064,6 +1093,12 @@ bool LLWearableHoldingPattern::pollMissingWearables()
{
// runway skip here?
LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
return true;
// [/SL:KB]
}
bool timed_out = isTimedOut();
@ -1496,7 +1531,10 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
{
LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(),
wearable_count-1);
removeCOFItemLinks(item_id, cb);
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
removeCOFItemLinks(item_id, NULL, true);
// [/SL:KB]
// removeCOFItemLinks(item_id, cb);
}
items_to_link.push_back(item_to_wear);
@ -1919,7 +1957,10 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Check whether it's the base outfit.
if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
// if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1)
if ( (outfit_cat_id.isNull()) || ((outfit_cat_id == getBaseOutfitUUID()) && (!isOutfitDirty())) )
// [/SL:KB]
{
return false;
}
@ -2032,7 +2073,10 @@ void LLAppearanceMgr::filterWearableItems(
S32 size = items_by_type[i].size();
if (size <= 0)
continue;
S32 start_index = llmax(0,size-max_per_type);
// S32 start_index = llmax(0,size-max_per_type);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.0)
S32 start_index = llmax(0, size - ((LLWearableType::getAllowMultiwear((LLWearableType::EType)i)) ? max_per_type : 1));
// [/SL:KB[
for (S32 j = start_index; j<size; j++)
{
items.push_back(items_by_type[i][j]);
@ -2357,14 +2401,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
{
//checking integrity of the COF in terms of ordering of wearables,
//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-03-01 (Catznip-3.7)
// Ordering information is pre-applied locally so no reason to reason to wait on the inventory backend
updateClothingOrderingInfo(LLUUID::null);
// [/SL:KB]
// As with enforce_item_restrictions handling above, we want
// to wait for the update callbacks, then (finally!) call
// updateAppearanceFromCOF() with no additional COF munging needed.
LLPointer<LLInventoryCallback> cb(
new LLUpdateAppearanceOnDestroy(false, false, post_update_func));
updateClothingOrderingInfo(LLUUID::null, cb);
return;
// // As with enforce_item_restrictions handling above, we want
// // to wait for the update callbacks, then (finally!) call
// // updateAppearanceFromCOF() with no additional COF munging needed.
// LLPointer<LLInventoryCallback> cb(
// new LLUpdateAppearanceOnDestroy(false, false, post_update_func));
// updateClothingOrderingInfo(LLUUID::null, cb);
// return;
}
if (!validateClothingOrderingInfo())
@ -2397,6 +2445,13 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
remove_non_link_items(wear_items);
remove_non_link_items(obj_items);
remove_non_link_items(gest_items);
// [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-2.4)
// Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_LAYERS
removeDuplicateItems(wear_items);
removeDuplicateItems(obj_items);
removeDuplicateItems(gest_items);
filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_LAYERS, LLAgentWearables::MAX_CLOTHING_LAYERS);
// [/SL:KB]
dumpItemArray(wear_items,"asset_dump: wear_item");
dumpItemArray(obj_items,"asset_dump: obj_item");
@ -2408,6 +2463,69 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
<< " descendent_count " << cof->getDescendentCount()
<< " viewer desc count " << cof->getViewerDescendentCount() << LL_ENDL;
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
// Include attachments which should be in COF but don't have their link created yet
std::set<LLUUID> pendingAttachments;
if (LLAttachmentsMgr::instance().getPendingAttachments(pendingAttachments))
{
for (const LLUUID& idAttachItem : pendingAttachments)
{
if ( (!gAgentAvatarp->isWearingAttachment(idAttachItem)) || (isLinkedInCOF(idAttachItem)) )
{
LLAttachmentsMgr::instance().clearPendingAttachmentLink(idAttachItem);
continue;
}
LLViewerInventoryItem* pAttachItem = gInventory.getItem(idAttachItem);
if (pAttachItem)
{
obj_items.push_back(pAttachItem);
}
}
}
// (Start of LL code from LLWearableHoldingPattern::onAllComplete())
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.size() << " attachments" << LL_ENDL;
LLAgentWearables::llvo_vec_t objects_to_remove;
LLAgentWearables::llvo_vec_t objects_to_retain;
LLInventoryModel::item_array_t items_to_add;
LLAgentWearables::findAttachmentsAddRemoveInfo(obj_items, objects_to_remove, objects_to_retain, items_to_add);
// Here we remove the attachment pos overrides for *all*
// attachments, even those that are not being removed. This is
// needed to get joint positions all slammed down to their
// pre-attachment states.
gAgentAvatarp->clearAttachmentOverrides();
// (End of LL code)
// Take off the attachments that will no longer be in the outfit.
// (but don't remove attachments until avatar is fully loaded - should reduce random attaching/detaching/reattaching at log-on)
if (gAgentAvatarp->isFullyLoaded())
{
LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() << " attachments" << LL_ENDL;
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
}
// (Start of LL code from LLWearableHoldingPattern::onAllComplete())
// Restore attachment pos overrides for the attachments that are remaining in the outfit.
for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); it != objects_to_retain.end(); ++it)
{
LLViewerObject *objectp = *it;
gAgentAvatarp->addAttachmentOverridesForObject(objectp);
}
// Add new attachments to match those requested.
LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
LLAgentWearables::userAttachMultipleAttachments(items_to_add);
// (End of LL code)
}
// [/SL:KB]
if(!wear_items.size())
{
LLNotificationsUtil::add("CouldNotPutOnOutfit");
@ -2422,7 +2540,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
LLTimer hp_block_timer;
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
holder->setObjItems(obj_items);
// holder->setObjItems(obj_items);
holder->setGestItems(gest_items);
// Note: can't do normal iteration, because if all the
@ -2950,7 +3068,10 @@ private:
LLPointer<LLInventoryCallback> mCB;
};
void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
//void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb, bool immediate_delete)
// [/SL:KB]
{ LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
@ -2962,7 +3083,17 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve
const LLInventoryItem* item = item_array.at(i).get();
if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
{
if (item->getType() == LLAssetType::AT_OBJECT)
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
if (rlv_handler_t::isEnabled())
{
RLV_ASSERT(rlvPredCanRemoveItem(item));
}
// [/RLVa:KB]
// if (item->getType() == LLAssetType::AT_OBJECT)
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
if (immediate_delete)
// [/RLVa:KB]
{
// Immediate delete
remove_inventory_item(item->getUUID(), cb, true);
@ -3870,14 +4001,23 @@ void LLAppearanceMgr::wearBaseOutfit()
updateCOF(base_outfit_id);
}
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
//void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/)
// [/SL:KB]
{
if (ids_to_remove.empty())
{
LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
return;
}
LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
// LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
if (!cb)
{
cb = new LLUpdateAppearanceOnDestroy;
}
// [/SL:KB]
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
@ -3891,16 +4031,28 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
continue;
}
removeCOFItemLinks(linked_item_id, cb);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
removeCOFItemLinks(linked_item_id, cb, immediate_delete);
// [/SL:KB]
// removeCOFItemLinks(linked_item_id, cb);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
LLAttachmentsMgr::instance().clearPendingAttachmentLink(linked_item_id);
// [/SL:KB]
addDoomedTempAttachment(linked_item_id);
}
}
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
//void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/)
// [/SL:KB]
{
uuid_vec_t ids_to_remove;
ids_to_remove.push_back(id_to_remove);
removeItemsFromAvatar(ids_to_remove);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
removeItemsFromAvatar(ids_to_remove, cb, immediate_delete);
// [/SL:KB]
// removeItemsFromAvatar(ids_to_remove);
}

View File

@ -147,6 +147,9 @@ public:
// Attachment link management
void unregisterAttachment(const LLUUID& item_id);
void registerAttachment(const LLUUID& item_id);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
bool getAttachmentInvLinkEnable() { return mAttachmentInvLinkEnabled; }
// [/SL:KB]
void setAttachmentInvLinkEnable(bool val);
// Add COF link to individual item.
@ -158,7 +161,10 @@ public:
bool isLinkedInCOF(const LLUUID& item_id);
// Remove COF entries
void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL);
// void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL);
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
// [/SL:KB]
void removeCOFLinksOfType(LLWearableType::EType type, LLPointer<LLInventoryCallback> cb = NULL);
void removeAllClothesFromAvatar();
void removeAllAttachmentsFromAvatar();
@ -194,8 +200,15 @@ public:
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
void removeItemsFromAvatar(const uuid_vec_t& item_ids);
void removeItemFromAvatar(const LLUUID& item_id);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
void removeItemFromAvatar(const LLUUID& id_to_remove) { removeItemFromAvatar(id_to_remove, NULL, false); }
void removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/);
void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) { removeItemsFromAvatar(ids_to_remove, NULL, false); }
void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/);
// [/SL:KB]
// void removeItemsFromAvatar(const uuid_vec_t& item_ids);
// void removeItemFromAvatar(const LLUUID& item_id);
void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
@ -228,6 +241,9 @@ public:
static void onIdle(void *);
void requestServerAppearanceUpdate();
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7)
void syncCofVersionAndRefresh();
// [/SL:KB]
void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
std::string getAppearanceServiceURL() const;

View File

@ -92,6 +92,9 @@
#include "llprogressview.h"
#include "llvocache.h"
#include "llvopartgroup.h"
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
#include "llappearancemgr.h"
// [/SL:KB]
#include "llweb.h"
#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
@ -5406,6 +5409,11 @@ void LLAppViewer::disconnectViewer()
// close inventory interface, close all windows
LLSidepanelInventory::cleanup();
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
// Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false);
// [/SL:KB]
gAgentWearables.cleanup();
gAgentCamera.cleanup();
// Also writes cached agent settings to gSavedSettings

View File

@ -41,10 +41,31 @@ const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F;
const F32 MIN_RETRY_REQUEST_TIME = 5.0F;
const F32 MAX_BAD_COF_TIME = 30.0F;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
class LLRegisterAttachmentCallback : public LLRequestServerAppearanceUpdateOnDestroy
{
public:
LLRegisterAttachmentCallback()
: LLRequestServerAppearanceUpdateOnDestroy()
{
}
~LLRegisterAttachmentCallback() override
{
}
void fire(const LLUUID& idItem) override
{
LLAttachmentsMgr::instance().onRegisterAttachmentComplete(idItem);
LLRequestServerAppearanceUpdateOnDestroy::fire(idItem);
}
};
// [/SL:KB]
LLAttachmentsMgr::LLAttachmentsMgr():
mAttachmentRequests("attach",MIN_RETRY_REQUEST_TIME),
mDetachRequests("detach",MIN_RETRY_REQUEST_TIME),
mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME)
mDetachRequests("detach",MIN_RETRY_REQUEST_TIME)
// , mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME)
{
}
@ -79,6 +100,11 @@ void LLAttachmentsMgr::addAttachmentRequest(const LLUUID& item_id,
void LLAttachmentsMgr::onAttachmentRequested(const LLUUID& item_id)
{
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
if (item_id.isNull())
return;
// [/SL:KB]
LLViewerInventoryItem *item = gInventory.getItem(item_id);
LL_DEBUGS("Avatar") << "ATT attachment was requested "
<< (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
@ -112,7 +138,7 @@ void LLAttachmentsMgr::onIdle()
expireOldDetachRequests();
checkInvalidCOFLinks();
// checkInvalidCOFLinks();
spamStatusInfo();
}
@ -221,6 +247,13 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
{
if (mRecentlyArrivedAttachments.size())
{
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
if (!LLAppearanceMgr::instance().getAttachmentInvLinkEnable())
{
return;
}
// [/SL:KB]
// One or more attachments have arrived but have not yet been
// processed for COF links
if (mAttachmentRequests.empty())
@ -259,17 +292,63 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
}
if (ids_to_link.size())
{
LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin();
uuid_it != ids_to_link.end(); ++uuid_it)
{
LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb);
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
LLPointer<LLInventoryCallback> cb = new LLRegisterAttachmentCallback();
for (const LLUUID& idAttach : ids_to_link)
{
if (std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), idAttach) == mPendingAttachLinks.end())
{
LLAppearanceMgr::instance().addCOFItemLink(idAttach, cb);
mPendingAttachLinks.insert(idAttach);
}
}
// [/SL:KB]
// LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
// for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin();
// uuid_it != ids_to_link.end(); ++uuid_it)
// {
// LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb);
// }
}
mRecentlyArrivedAttachments.clear();
}
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
bool LLAttachmentsMgr::getPendingAttachments(std::set<LLUUID>& ids) const
{
ids.clear();
// Returns the union of the LL maintained list of attachments that are waiting for link creation and our maintained list of attachments that are pending link creation
set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin()));
return !ids.empty();
}
void LLAttachmentsMgr::clearPendingAttachmentLink(const LLUUID& idItem)
{
mPendingAttachLinks.erase(idItem);
}
void LLAttachmentsMgr::onRegisterAttachmentComplete(const LLUUID& idAttachLink)
{
const LLViewerInventoryItem* pAttachLink = gInventory.getItem(idAttachLink);
if (!pAttachLink)
return;
const LLUUID& idAttachBase = pAttachLink->getLinkedUUID();
// Remove the attachment from the pending list
clearPendingAttachmentLink(idAttachBase);
// It may have been detached already in which case we should remove the COF link
if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idAttachBase)) )
{
LLAppearanceMgr::instance().removeCOFItemLinks(idAttachBase, NULL, true);
}
}
// [/SL:KB]
LLAttachmentsMgr::LLItemRequestTimes::LLItemRequestTimes(const std::string& op_name, F32 timeout):
mOpName(op_name),
mTimeout(timeout)
@ -398,6 +477,11 @@ void LLAttachmentsMgr::onDetachRequested(const LLUUID& inv_item_id)
void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
{
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
// (mRecentlyArrivedAttachments doesn't need pruning since it'll check the attachment is actually worn before linking)
clearPendingAttachmentLink(inv_item_id);
// [/SL:KB]
LLTimer timer;
LLInventoryItem *item = gInventory.getItem(inv_item_id);
if (mDetachRequests.getTime(inv_item_id, timer))
@ -416,18 +500,25 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
<< (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
}
LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
<< (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
mQuestionableCOFLinks.addTime(inv_item_id);
// LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
// << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
// mQuestionableCOFLinks.addTime(inv_item_id);
}
bool LLAttachmentsMgr::isAttachmentStateComplete() const
{
return mPendingAttachments.empty()
&& mAttachmentRequests.empty()
&& mDetachRequests.empty()
&& mRecentlyArrivedAttachments.empty()
&& mQuestionableCOFLinks.empty();
// [SL:KB] - Patch: Appearance-Misc | Checked: Catznip-4.3
return mPendingAttachments.empty()
&& mAttachmentRequests.empty()
&& mDetachRequests.empty()
&& mRecentlyArrivedAttachments.empty()
&& mPendingAttachLinks.empty();
// [/SL:KB]
// return mPendingAttachments.empty()
// && mAttachmentRequests.empty()
// && mDetachRequests.empty()
// && mRecentlyArrivedAttachments.empty()
// && mQuestionableCOFLinks.empty();
}
// Check for attachments that are (a) linked in COF and (b) not
@ -450,54 +541,54 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const
//
// See related: MAINT-5070, MAINT-4409
//
void LLAttachmentsMgr::checkInvalidCOFLinks()
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
for (S32 i=0; i<item_array.size(); i++)
{
const LLViewerInventoryItem* inv_item = item_array.at(i).get();
const LLUUID& item_id = inv_item->getLinkedUUID();
if (inv_item->getType() == LLAssetType::AT_OBJECT)
{
LLTimer timer;
bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
if (is_wearing_attachment && is_flagged_questionable)
{
LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now "
<< (is_wearing_attachment ? "attached " : "")
<<"removing flag after "
<< timer.getElapsedTimeF32() << " item "
<< inv_item->getName() << " id " << item_id << LL_ENDL;
mQuestionableCOFLinks.removeTime(item_id);
}
}
}
for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
it != mQuestionableCOFLinks.end(); )
{
LLItemRequestTimes::iterator curr_it = it;
++it;
const LLUUID& item_id = curr_it->first;
LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
{
if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
{
LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
<< curr_it->second.getElapsedTimeF32() << " seconds for "
<< (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
}
mQuestionableCOFLinks.erase(curr_it);
continue;
}
}
}
//void LLAttachmentsMgr::checkInvalidCOFLinks()
//{
// LLInventoryModel::cat_array_t cat_array;
// LLInventoryModel::item_array_t item_array;
// gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
// cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
// for (S32 i=0; i<item_array.size(); i++)
// {
// const LLViewerInventoryItem* inv_item = item_array.at(i).get();
// const LLUUID& item_id = inv_item->getLinkedUUID();
// if (inv_item->getType() == LLAssetType::AT_OBJECT)
// {
// LLTimer timer;
// bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
// bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
// if (is_wearing_attachment && is_flagged_questionable)
// {
// LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now "
// << (is_wearing_attachment ? "attached " : "")
// <<"removing flag after "
// << timer.getElapsedTimeF32() << " item "
// << inv_item->getName() << " id " << item_id << LL_ENDL;
// mQuestionableCOFLinks.removeTime(item_id);
// }
// }
// }
//
// for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
// it != mQuestionableCOFLinks.end(); )
// {
// LLItemRequestTimes::iterator curr_it = it;
// ++it;
// const LLUUID& item_id = curr_it->first;
// LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
// if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
// {
// if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
// {
// LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
// << curr_it->second.getElapsedTimeF32() << " seconds for "
// << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
// LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
// }
// mQuestionableCOFLinks.erase(curr_it);
// continue;
// }
// }
//}
void LLAttachmentsMgr::spamStatusInfo()
{
@ -528,3 +619,28 @@ void LLAttachmentsMgr::spamStatusInfo()
}
#endif
}
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
void LLAttachmentsMgr::refreshAttachments()
{
if (!isAgentAvatarValid())
return;
for (const auto& kvpAttachPt : gAgentAvatarp->mAttachmentPoints)
{
for (const LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects)
{
const LLUUID& idItem = pAttachObj->getAttachmentItemID();
if ( (mAttachmentRequests.wasRequestedRecently(idItem)) || (pAttachObj->isTempAttachment()) )
continue;
AttachmentsInfo attachment;
attachment.mItemID = idItem;
attachment.mAttachmentPt = kvpAttachPt.first;
attachment.mAdd = true;
mPendingAttachments.push_back(attachment);
mAttachmentRequests.addTime(idItem);
}
}
}
// [/SL:KB]

View File

@ -89,6 +89,16 @@ public:
bool isAttachmentStateComplete() const;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
public:
void clearPendingAttachmentLink(const LLUUID& idItem);
bool getPendingAttachments(std::set<LLUUID>& ids) const;
void refreshAttachments();
protected:
void onRegisterAttachmentComplete(const LLUUID& idAttachLink);
friend class LLRegisterAttachmentCallback;
// [/SL:KB]
private:
class LLItemRequestTimes: public std::map<LLUUID,LLTimer>
@ -111,7 +121,7 @@ private:
void linkRecentlyArrivedAttachments();
void expireOldAttachmentRequests();
void expireOldDetachRequests();
void checkInvalidCOFLinks();
// void checkInvalidCOFLinks();
void spamStatusInfo();
// Attachments that we are planning to rez but haven't requested from the server yet.
@ -127,8 +137,13 @@ private:
std::set<LLUUID> mRecentlyArrivedAttachments;
LLTimer mCOFLinkBatchTimer;
// Attachments that are linked in the COF but may be invalid.
LLItemRequestTimes mQuestionableCOFLinks;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
// Attachments that have pending link creation
std::set<LLUUID> mPendingAttachLinks;
// [/SL:KB]
// // Attachments that are linked in the COF but may be invalid.
// LLItemRequestTimes mQuestionableCOFLinks;
};
#endif

View File

@ -64,6 +64,15 @@ void LLAdaptiveRetryPolicy::reset()
init();
}
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
// virtual
void LLAdaptiveRetryPolicy::cancelRetry()
{
// This relies on the current implementation where mShouldRetry is set to true only on initialization
mShouldRetry = false;
}
// [/SL:KB]
bool LLAdaptiveRetryPolicy::getRetryAfter(const LLSD& headers, F32& retry_header_time)
{
return (headers.has(HTTP_IN_HEADER_RETRY_AFTER)

View File

@ -55,6 +55,9 @@ public:
virtual bool shouldRetry(F32& seconds_to_wait) const = 0;
virtual void reset() = 0;
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
virtual void cancelRetry() = 0;
// [/SL:KB]
};
// Very general policy with geometric back-off after failures,
@ -68,6 +71,9 @@ public:
void onSuccess();
void reset();
// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
/*virtual*/ void cancelRetry();
// [/SL:KB]
// virtual
void onFailure(S32 status, const LLSD& headers);

View File

@ -4165,6 +4165,9 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_agent_inventory = isAgentInventory();
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4)
const bool is_outfit = (type == LLFolderType::FT_OUTFIT);
// [/SL:KB]
// Only enable calling-card related options for non-system folders.
if (!is_system_folder && is_agent_inventory)
@ -4216,7 +4219,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
disabled_items.push_back(std::string("Remove From Outfit"));
}
}
if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
// if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4)
if ( ((is_outfit) && (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))) ||
((!is_outfit) && (gAgentWearables.isCOFChangeInProgress())) )
// [/SL:KB]
{
disabled_items.push_back(std::string("Replace Outfit"));
}
@ -6188,7 +6195,11 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
else if(item && item->isFinished())
{
// must be in library. copy it to our inventory and put it on.
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
// LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4)
// "Wear" from inventory replaces, so library items should too
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, true));
// [/SL;KB]
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@ -6689,56 +6700,56 @@ void LLWearableBridge::wearAddOnAvatar()
}
// static
void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
{
LLViewerInventoryItem* item = NULL;
item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
if(item)
{
if(item->getAssetUUID() == wearable->getAssetID())
{
gAgentWearables.setWearableItem(item, wearable);
gInventory.notifyObservers();
//self->getFolderItem()->refreshFromRoot();
}
else
{
LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
}
}
}
delete item_id;
}
//void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
//{
// LLUUID* item_id = (LLUUID*) userdata;
// if(wearable)
// {
// LLViewerInventoryItem* item = NULL;
// item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
// if(item)
// {
// if(item->getAssetUUID() == wearable->getAssetID())
// {
// gAgentWearables.setWearableItem(item, wearable);
// gInventory.notifyObservers();
// //self->getFolderItem()->refreshFromRoot();
// }
// else
// {
// LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
// }
// }
// }
// delete item_id;
//}
// static
// BAP remove the "add" code path once everything is fully COF-ified.
void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
{
LLViewerInventoryItem* item = NULL;
item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
if(item)
{
if(item->getAssetUUID() == wearable->getAssetID())
{
bool do_append = true;
gAgentWearables.setWearableItem(item, wearable, do_append);
gInventory.notifyObservers();
//self->getFolderItem()->refreshFromRoot();
}
else
{
LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
}
}
}
delete item_id;
}
//void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
//{
// LLUUID* item_id = (LLUUID*) userdata;
// if(wearable)
// {
// LLViewerInventoryItem* item = NULL;
// item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
// if(item)
// {
// if(item->getAssetUUID() == wearable->getAssetID())
// {
// bool do_append = true;
// gAgentWearables.setWearableItem(item, wearable, do_append);
// gInventory.notifyObservers();
// //self->getFolderItem()->refreshFromRoot();
// }
// else
// {
// LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
// }
// }
// }
// delete item_id;
//}
// static
BOOL LLWearableBridge::canEditOnAvatar(void* user_data)

View File

@ -544,10 +544,10 @@ public:
static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu
static BOOL canWearOnAvatar( void* userdata );
static void onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
// static void onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
void wearOnAvatar();
static void onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
// static void onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
void wearAddOnAvatar();
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu

View File

@ -520,10 +520,11 @@ BOOL get_is_item_worn(const LLUUID& id)
return FALSE;
// Consider the item as worn if it has links in COF.
if (LLAppearanceMgr::instance().isLinkedInCOF(id))
{
return TRUE;
}
// [SL:KB] - The code below causes problems across the board so it really just needs to go
// if (LLAppearanceMgr::instance().isLinkedInCOF(id))
// {
// return TRUE;
// }
switch(item->getType())
{

View File

@ -2491,7 +2491,7 @@ void LLSelectMgr::logNoOp(LLSelectNode* node, void *)
// static
void LLSelectMgr::logAttachmentRequest(LLSelectNode* node, void *)
{
LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID);
// LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID);
}
// static

View File

@ -1737,7 +1737,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
{
if(mSource == SOURCE_LIBRARY)
{
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
// LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-2.2)
// Make this behave consistent with dad3dWearItem
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, !(mask & MASK_CONTROL)));
// [/SL:KB]
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@ -1748,7 +1752,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
}
else
{
rez_attachment(item, 0);
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-2.2)
// Make this behave consistent with dad3dWearItem
rez_attachment(item, 0, !(mask & MASK_CONTROL));
// [/SL:KB]
// rez_attachment(item, 0);
}
}
return ACCEPT_YES_SINGLE;

View File

@ -121,7 +121,10 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin
else if(item && item->isFinished())
{
// must be in library. copy it to our inventory and put it on.
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
// LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4)
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false));
// [/SL;KB]
copy_inventory_item(gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),

View File

@ -997,7 +997,10 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
}
}
void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace)
// [/SL:KB]
{
if (inv_item.isNull())
return;
@ -1005,7 +1008,10 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
if (item)
{
rez_attachment(item, attachmentp);
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
rez_attachment(item, attachmentp, replace);
// [/SL:KB]
// rez_attachment(item, attachmentp);
}
}

View File

@ -253,7 +253,10 @@ public:
class LLViewerJointAttachment;
void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace);
// [/SL:KB]
//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
void activate_gesture_cb(const LLUUID& inv_item);

View File

@ -28,6 +28,9 @@
#include "llviewerjointattachment.h"
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
#include "llagent.h"
// [/SL:KB]
#include "llviewercontrol.h"
#include "lldrawable.h"
#include "llgl.h"
@ -166,7 +169,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
//-----------------------------------------------------------------------------
BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
{
object->extractAttachmentItemID();
// object->extractAttachmentItemID();
// Same object reattached
if (isObjectAttached(object))
@ -177,17 +180,39 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
// re-connect object to the joint correctly
}
// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-01-13 (Catznip-2.4)
// LLViewerJointAttachment::removeObject() sets the object's item to the NULL UUID so we need to extract it *after* the block above
object->extractAttachmentItemID();
// [/SL:KB]
// Two instances of the same inventory item attached --
// Request detach, and kill the object in the meantime.
if (getAttachedObject(object->getAttachmentItemID()))
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
if (LLViewerObject* pAttachObj = getAttachedObject(object->getAttachmentItemID()))
{
LL_INFOS() << "(same object re-attached)" << LL_ENDL;
object->markDead();
// If this happens to be attached to self, then detach.
LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
return FALSE;
}
pAttachObj->markDead();
if (pAttachObj->permYouOwner())
{
gMessageSystem->newMessage("ObjectDetach");
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachObj->getLocalID());
gMessageSystem->sendReliable(gAgent.getRegionHost());
}
}
// [/SL:KB]
// if (getAttachedObject(object->getAttachmentItemID()))
// {
// LL_INFOS() << "(same object re-attached)" << LL_ENDL;
// object->markDead();
//
// // If this happens to be attached to self, then detach.
// LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
// return FALSE;
// }
mAttachedObjects.push_back(object);
setupDrawable(object);
@ -442,7 +467,10 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
++iter)
{
const LLViewerObject* attached_object = (*iter);
if (attached_object->getAttachmentItemID() == object_id)
// if (attached_object->getAttachmentItemID() == object_id)
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
if ( (attached_object->getAttachmentItemID() == object_id) && (!attached_object->isDead()) )
// [/SL:KB]
{
return attached_object;
}

View File

@ -49,6 +49,9 @@
#include "llagentui.h"
#include "llagentwearables.h"
#include "llagentpilot.h"
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
#include "llattachmentsmgr.h"
// [/SL:KB]
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldaycyclemanager.h"
@ -1930,6 +1933,15 @@ class LLAdvancedRebakeTextures : public view_listener_t
};
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
void handle_refresh_attachments()
{
if (isAgentAvatarValid())
gAgentAvatarp->rebuildAttachments();
LLAttachmentsMgr::instance().refreshAttachments();
}
// [/SL:KB]
#if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
///////////////////////////
// DEBUG AVATAR TEXTURES //
@ -4062,6 +4074,13 @@ void handle_reset_view()
gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
reset_view_final( TRUE );
LLFloaterCamera::resetCameraMode();
// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
if (isAgentAvatarValid())
{
gAgentAvatarp->rebuildAttachments();
}
// [/SL:KB]
}
class LLViewResetView : public view_listener_t
@ -6054,6 +6073,9 @@ class LLAvatarResetSkeleton: public view_listener_t
if(avatar)
{
avatar->resetSkeleton(false);
// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
avatar->rebuildAttachments();
// [/SL:KB]
}
return true;
}
@ -6067,6 +6089,9 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t
if (avatar)
{
avatar->resetSkeleton(true);
// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
avatar->rebuildAttachments();
// [/SL:KB]
}
return true;
}
@ -8038,6 +8063,9 @@ void handle_rebake_textures(void*)
gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
{
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7)
// LLAppearanceMgr::instance().syncCofVersionAndRefresh();
// [/SL:KB]
LLAppearanceMgr::instance().requestServerAppearanceUpdate();
}
}
@ -8985,6 +9013,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
commit.add("Advanced.RefreshAttachments", boost::bind(&handle_refresh_attachments));
// [/SL:KB]
view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
// Advanced > Network

View File

@ -6824,6 +6824,27 @@ LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) cons
return NULL;
}
// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
void LLVOAvatar::rebuildAttachments()
{
for (const auto& kvpAttachPt : mAttachmentPoints)
{
for (LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects)
{
if (LLVOVolume* pAttachVol = (pAttachObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pAttachObj) : nullptr)
{
pAttachVol->forceLOD(3);
for (LLViewerObject* pChildObj : pAttachObj->getChildren())
{
if (LLVOVolume* pChildVol = (pChildObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pChildObj) : nullptr)
pAttachVol->forceLOD(3);
}
}
}
}
}
// [/SL:KB]
// virtual
void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset)
{
@ -7140,7 +7161,11 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
BOOL LLVOAvatar::isFullyLoaded() const
{
return (mRenderUnloadedAvatar || mFullyLoaded);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
// Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp
return (mRenderUnloadedAvatar && !isSelf()) ||(mFullyLoaded);
// [/SL:KB]
// return (mRenderUnloadedAvatar || mFullyLoaded);
}
bool LLVOAvatar::isTooComplex() const

View File

@ -739,6 +739,9 @@ public:
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
void rebuildAttachments();
// [/SL:KB]
protected:
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);

View File

@ -3696,6 +3696,20 @@ U32 LLVOVolume::getHighLODTriangleCount()
return ret;
}
// [FS:Beq] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
void LLVOVolume::forceLOD(S32 lod)
{
// [SL:KB] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
if (mDrawable.isNull())
return;
// [/SL:KB]
mLOD = lod;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
mLODChanged = true;
}
// [/FS]
//static
void LLVOVolume::preUpdateGeom()
{

View File

@ -154,6 +154,9 @@ public:
LLVector3 volumeDirectionToAgent(const LLVector3& dir) const;
// [FS:Beq] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
void forceLOD(S32 lod);
// [/FS]
BOOL getVolumeChanged() const { return mVolumeChanged; }
/*virtual*/ F32 getRadius() const { return mVObjRadius; };

View File

@ -99,7 +99,23 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
{
BOOL isNewWearable = FALSE;
LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
LLViewerWearable* wearable = NULL; // NULL indicates failure
// LLViewerWearable* wearable = NULL; // NULL indicates failure
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-08-13 (Catznip-2.1)
LLViewerWearable* wearable = get_if_there(LLWearableList::instance().mList, uuid, (LLViewerWearable*)NULL);
if (wearable)
{
LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
LL_DEBUGS("Wearable") << wearable << LL_ENDL;
if(data->mCallback)
{
data->mCallback(wearable, data->mUserdata);
}
delete data;
return;
}
// [/SL:KB]
LLAvatarAppearance *avatarp = data->mAvatarp;
if( !filename )

View File

@ -1485,6 +1485,12 @@
<menu_item_call.on_click
function="Advanced.RebakeTextures" />
</menu_item_call>
<menu_item_call
label="Refresh Attachments"
name="Refresh Attachments">
<menu_item_call.on_click
function="Advanced.RefreshAttachments" />
</menu_item_call>
<menu_item_call
label="Set UI Size to Default"
name="Set UI Size to Default">