@@ -42,10 +42,19 @@ const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F;
42
42
const F32 MIN_RETRY_REQUEST_TIME = 5 .0F ;
43
43
const F32 MAX_BAD_COF_TIME = 30 .0F ;
44
44
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
+
45
55
LLAttachmentsMgr::LLAttachmentsMgr ():
46
56
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)
49
58
{
50
59
}
51
60
@@ -113,8 +122,6 @@ void LLAttachmentsMgr::onIdle()
113
122
114
123
expireOldDetachRequests ();
115
124
116
- checkInvalidCOFLinks ();
117
-
118
125
spamStatusInfo ();
119
126
}
120
127
@@ -222,6 +229,11 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
222
229
{
223
230
if (mRecentlyArrivedAttachments .size ())
224
231
{
232
+ if (!LLAppearanceMgr::instance ().getAttachmentInvLinkEnable ())
233
+ {
234
+ return ;
235
+ }
236
+
225
237
// One or more attachments have arrived but have not yet been
226
238
// processed for COF links
227
239
if (mAttachmentRequests .empty ())
@@ -268,17 +280,49 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
268
280
}
269
281
if (ids_to_link.size ())
270
282
{
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)
274
285
{
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
+ }
276
291
}
277
292
}
278
293
mRecentlyArrivedAttachments .clear ();
279
294
}
280
295
}
281
296
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
+
282
326
LLAttachmentsMgr::LLItemRequestTimes::LLItemRequestTimes (const std::string& op_name, F32 timeout):
283
327
mOpName(op_name),
284
328
mTimeout(timeout)
@@ -407,6 +451,8 @@ void LLAttachmentsMgr::onDetachRequested(const LLUUID& inv_item_id)
407
451
408
452
void LLAttachmentsMgr::onDetachCompleted (const LLUUID& inv_item_id)
409
453
{
454
+ clearPendingAttachmentLink (inv_item_id);
455
+
410
456
LLTimer timer;
411
457
LLInventoryItem *item = gInventory .getItem (inv_item_id);
412
458
if (mDetachRequests .getTime (inv_item_id, timer))
@@ -428,10 +474,6 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
428
474
{
429
475
LL_DEBUGS (" Avatar" ) << " ATT detach on shutdown for " << (item ? item->getName () : " UNKNOWN" ) << " " << inv_item_id << LL_ENDL;
430
476
}
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);
435
477
}
436
478
437
479
bool LLAttachmentsMgr::isAttachmentStateComplete () const
@@ -440,80 +482,7 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const
440
482
&& mAttachmentRequests .empty ()
441
483
&& mDetachRequests .empty ()
442
484
&& 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 ();
517
486
}
518
487
519
488
void LLAttachmentsMgr::spamStatusInfo ()
0 commit comments