Skip to content

Commit 33d317a

Browse files
committed
Resolve issues tracking worn attachments that aren't in COF yet (see PR for more details)
1 parent 9109310 commit 33d317a

File tree

5 files changed

+88
-92
lines changed

5 files changed

+88
-92
lines changed

indra/newview/llappearancemgr.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,23 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
25362536
// Update attachments to match those requested.
25372537
if (isAgentAvatarValid())
25382538
{
2539+
// Include attachments which should be in COF but don't have their link created yet
2540+
std::set<LLUUID> pendingAttachments;
2541+
LLAttachmentsMgr::instance().getPendingAttachments(pendingAttachments);
2542+
for (const LLUUID& idAttachItem : pendingAttachments)
2543+
{
2544+
if ( !gAgentAvatarp->isWearingAttachment(idAttachItem) || isLinkedInCOF(idAttachItem) )
2545+
{
2546+
LLAttachmentsMgr::instance().clearPendingAttachmentLink(idAttachItem);
2547+
continue;
2548+
}
2549+
2550+
if (LLViewerInventoryItem* pAttachItem = gInventory.getItem(idAttachItem))
2551+
{
2552+
obj_items.push_back(pAttachItem);
2553+
}
2554+
}
2555+
25392556
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.size() << " attachments" << LL_ENDL;
25402557
LLAgentWearables::llvo_vec_t objects_to_remove;
25412558
LLAgentWearables::llvo_vec_t objects_to_retain;
@@ -2562,7 +2579,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
25622579
}
25632580

25642581
// Take off the attachments that will no longer be in the outfit.
2565-
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
2582+
// (don't remove attachments until avatar is fully loaded - reduces random attaching/detaching/reattaching at log-on)
2583+
if (gAgentAvatarp->isFullyLoaded())
2584+
{
2585+
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
2586+
}
25662587

25672588
// Restore attachment pos overrides for the attachments that
25682589
// are remaining in the outfit.
@@ -4135,6 +4156,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, nul
41354156
continue;
41364157
}
41374158
removeCOFItemLinks(linked_item_id, cb);
4159+
LLAttachmentsMgr::instance().clearPendingAttachmentLink(linked_item_id);
41384160
addDoomedTempAttachment(linked_item_id);
41394161
}
41404162
}

indra/newview/llappearancemgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
150150
// Attachment link management
151151
void unregisterAttachment(const LLUUID& item_id);
152152
void registerAttachment(const LLUUID& item_id);
153+
bool getAttachmentInvLinkEnable() const { return mAttachmentInvLinkEnabled; }
153154
void setAttachmentInvLinkEnable(bool val);
154155

155156
// Add COF link to individual item.

indra/newview/llattachmentsmgr.cpp

Lines changed: 55 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,19 @@ const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F;
4242
const F32 MIN_RETRY_REQUEST_TIME = 5.0F;
4343
const F32 MAX_BAD_COF_TIME = 30.0F;
4444

45+
class LLRegisterAttachmentCallback : public LLRequestServerAppearanceUpdateOnDestroy
46+
{
47+
public:
48+
void fire(const LLUUID& item_id) override
49+
{
50+
LLAttachmentsMgr::instance().onRegisterAttachmentComplete(item_id);
51+
LLRequestServerAppearanceUpdateOnDestroy::fire(item_id);
52+
}
53+
};
54+
4555
LLAttachmentsMgr::LLAttachmentsMgr():
4656
mAttachmentRequests("attach",MIN_RETRY_REQUEST_TIME),
47-
mDetachRequests("detach",MIN_RETRY_REQUEST_TIME),
48-
mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME)
57+
mDetachRequests("detach",MIN_RETRY_REQUEST_TIME)
4958
{
5059
}
5160

@@ -113,8 +122,6 @@ void LLAttachmentsMgr::onIdle()
113122

114123
expireOldDetachRequests();
115124

116-
checkInvalidCOFLinks();
117-
118125
spamStatusInfo();
119126
}
120127

@@ -222,6 +229,11 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
222229
{
223230
if (mRecentlyArrivedAttachments.size())
224231
{
232+
if (!LLAppearanceMgr::instance().getAttachmentInvLinkEnable())
233+
{
234+
return;
235+
}
236+
225237
// One or more attachments have arrived but have not yet been
226238
// processed for COF links
227239
if (mAttachmentRequests.empty())
@@ -268,17 +280,49 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
268280
}
269281
if (ids_to_link.size())
270282
{
271-
LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
272-
for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin();
273-
uuid_it != ids_to_link.end(); ++uuid_it)
283+
LLPointer<LLInventoryCallback> cb = new LLRegisterAttachmentCallback();
284+
for (const LLUUID& id_item: ids_to_link)
274285
{
275-
LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb);
286+
if (std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), id_item) == mPendingAttachLinks.end())
287+
{
288+
LLAppearanceMgr::instance().addCOFItemLink(id_item, cb);
289+
mPendingAttachLinks.insert(id_item);
290+
}
276291
}
277292
}
278293
mRecentlyArrivedAttachments.clear();
279294
}
280295
}
281296

297+
bool LLAttachmentsMgr::getPendingAttachments(std::set<LLUUID>& ids) const
298+
{
299+
ids.clear();
300+
301+
// Returns the combined set of attachments that are pending link creation and those that currently have an ongoing link creation process.
302+
set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin()));
303+
304+
return !ids.empty();
305+
}
306+
307+
void LLAttachmentsMgr::clearPendingAttachmentLink(const LLUUID& idItem)
308+
{
309+
mPendingAttachLinks.erase(idItem);
310+
}
311+
312+
void LLAttachmentsMgr::onRegisterAttachmentComplete(const LLUUID& id_item_link)
313+
{
314+
if (const LLUUID& id_item = gInventory.getLinkedItemID(id_item_link); id_item != id_item_link)
315+
{
316+
clearPendingAttachmentLink(id_item);
317+
318+
// It may have been detached already in which case we should remove the COF link
319+
if ( isAgentAvatarValid() && !gAgentAvatarp->isWearingAttachment(id_item) )
320+
{
321+
LLAppearanceMgr::instance().removeCOFItemLinks(id_item);
322+
}
323+
}
324+
}
325+
282326
LLAttachmentsMgr::LLItemRequestTimes::LLItemRequestTimes(const std::string& op_name, F32 timeout):
283327
mOpName(op_name),
284328
mTimeout(timeout)
@@ -407,6 +451,8 @@ void LLAttachmentsMgr::onDetachRequested(const LLUUID& inv_item_id)
407451

408452
void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
409453
{
454+
clearPendingAttachmentLink(inv_item_id);
455+
410456
LLTimer timer;
411457
LLInventoryItem *item = gInventory.getItem(inv_item_id);
412458
if (mDetachRequests.getTime(inv_item_id, timer))
@@ -428,10 +474,6 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
428474
{
429475
LL_DEBUGS("Avatar") << "ATT detach on shutdown for " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL;
430476
}
431-
432-
LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
433-
<< (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
434-
mQuestionableCOFLinks.addTime(inv_item_id);
435477
}
436478

437479
bool LLAttachmentsMgr::isAttachmentStateComplete() const
@@ -440,80 +482,7 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const
440482
&& mAttachmentRequests.empty()
441483
&& mDetachRequests.empty()
442484
&& mRecentlyArrivedAttachments.empty()
443-
&& mQuestionableCOFLinks.empty();
444-
}
445-
446-
// Check for attachments that are (a) linked in COF and (b) not
447-
// attached to the avatar. This is a rotten function to have to
448-
// include, because it runs the risk of either repeatedly spamming out
449-
// COF link removals if they're failing for some reason, or getting
450-
// into a tug of war with some other sequence of events that's in the
451-
// process of adding the attachment in question. However, it's needed
452-
// because we have no definitive source of authority for what things
453-
// are actually supposed to be attached. Scripts, run on the server
454-
// side, can remove an attachment without our expecting it. If this
455-
// happens to an attachment that's just been added, then the COF link
456-
// creation may still be in flight, and we will have to delete the
457-
// link after it shows up.
458-
//
459-
// Note that we only flag items for possible link removal if they have
460-
// been previously detached. This means that an attachment failure
461-
// will leave the link in the COF, where it will hopefully resolve
462-
// correctly on relog.
463-
//
464-
// See related: MAINT-5070, MAINT-4409
465-
//
466-
void LLAttachmentsMgr::checkInvalidCOFLinks()
467-
{
468-
if (!gInventory.isInventoryUsable())
469-
{
470-
return;
471-
}
472-
LLInventoryModel::cat_array_t cat_array;
473-
LLInventoryModel::item_array_t item_array;
474-
gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
475-
cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
476-
for (S32 i=0; i<item_array.size(); i++)
477-
{
478-
const LLViewerInventoryItem* inv_item = item_array.at(i).get();
479-
const LLUUID& item_id = inv_item->getLinkedUUID();
480-
if (inv_item->getType() == LLAssetType::AT_OBJECT)
481-
{
482-
LLTimer timer;
483-
bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
484-
bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
485-
if (is_wearing_attachment && is_flagged_questionable)
486-
{
487-
LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now "
488-
<< (is_wearing_attachment ? "attached " : "")
489-
<<"removing flag after "
490-
<< timer.getElapsedTimeF32() << " item "
491-
<< inv_item->getName() << " id " << item_id << LL_ENDL;
492-
mQuestionableCOFLinks.removeTime(item_id);
493-
}
494-
}
495-
}
496-
497-
for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
498-
it != mQuestionableCOFLinks.end(); )
499-
{
500-
LLItemRequestTimes::iterator curr_it = it;
501-
++it;
502-
const LLUUID& item_id = curr_it->first;
503-
LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
504-
if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
505-
{
506-
if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
507-
{
508-
LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
509-
<< curr_it->second.getElapsedTimeF32() << " seconds for "
510-
<< (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
511-
LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
512-
}
513-
mQuestionableCOFLinks.erase(curr_it);
514-
continue;
515-
}
516-
}
485+
&& mPendingAttachLinks.empty();
517486
}
518487

519488
void LLAttachmentsMgr::spamStatusInfo()

indra/newview/llattachmentsmgr.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,14 @@ class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
8585
void onDetachRequested(const LLUUID& inv_item_id);
8686
void onDetachCompleted(const LLUUID& inv_item_id);
8787

88+
void clearPendingAttachmentLink(const LLUUID& idItem);
89+
bool getPendingAttachments(std::set<LLUUID>& ids) const;
8890
bool isAttachmentStateComplete() const;
8991

92+
protected:
93+
void onRegisterAttachmentComplete(const LLUUID& id_item_link);
94+
friend class LLRegisterAttachmentCallback;
95+
9096
private:
9197

9298
class LLItemRequestTimes: public std::map<LLUUID,LLTimer>
@@ -109,7 +115,6 @@ class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
109115
void linkRecentlyArrivedAttachments();
110116
void expireOldAttachmentRequests();
111117
void expireOldDetachRequests();
112-
void checkInvalidCOFLinks();
113118
void spamStatusInfo();
114119

115120
// Attachments that we are planning to rez but haven't requested from the server yet.
@@ -124,9 +129,8 @@ class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
124129
// Attachments that have arrived but have not been linked in the COF yet.
125130
std::set<LLUUID> mRecentlyArrivedAttachments;
126131
LLTimer mCOFLinkBatchTimer;
127-
128-
// Attachments that are linked in the COF but may be invalid.
129-
LLItemRequestTimes mQuestionableCOFLinks;
132+
// Attachments that have pending COF link creation
133+
std::set<LLUUID> mPendingAttachLinks;
130134
};
131135

132136
#endif

indra/newview/llvoavatar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8438,7 +8438,7 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading)
84388438

84398439
bool LLVOAvatar::isFullyLoaded() const
84408440
{
8441-
return (mRenderUnloadedAvatar || mFullyLoaded);
8441+
return (mRenderUnloadedAvatar && !isSelf()) || mFullyLoaded;
84428442
}
84438443

84448444
bool LLVOAvatar::isTooComplex() const

0 commit comments

Comments
 (0)