From 418aec4dd28f4e0a373232cc86324a35ffc4345f Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 13 Mar 2025 00:12:58 -0400 Subject: Quick fix for a friend status race condition on login. --- indra/newview/llcallingcard.cpp | 20 ++++++++++++++++++++ indra/newview/llcallingcard.h | 2 ++ indra/newview/llstartup.cpp | 11 +++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 8e9ab8f87f..549c7ed0e4 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -271,6 +271,22 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) << "]" << LL_ENDL; } } + + // It's possible that the buddy list getting propagated from the inventory may have happened after we actually got the buddy list. + // Any buddies that we got prior will reside in a special queue that we must process and update statuses accordingly with. + // Do that here. + // -Geenz 2025-03-12 + while (!mBuddyStatusQueue.empty()) + { + auto buddyStatus = mBuddyStatusQueue.front(); + mBuddyStatusQueue.pop(); + + if (mBuddyInfo.find(buddyStatus.first) != mBuddyInfo.end()) + { + setBuddyOnline(buddyStatus.first, buddyStatus.second); + } + } + // do not notify observers here - list can be large so let it be done on idle. return new_buddy_count; @@ -335,6 +351,8 @@ void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online) { LL_WARNS() << "!! No buddy info found for " << id << ", setting to " << (is_online ? "Online" : "Offline") << LL_ENDL; + LL_WARNS() << "Did we receive a buddy status update before the buddy info?" << LL_ENDL; + mBuddyStatusQueue.push(std::make_pair(id, is_online)); } } @@ -706,6 +724,8 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { LL_WARNS() << "Received online notification for unknown buddy: " << agent_id << " is " << (online ? "ONLINE" : "OFFLINE") << LL_ENDL; + LL_WARNS() << "Adding buddy to buddy queue." << LL_ENDL; + mBuddyStatusQueue.push(std::make_pair(agent_id, true)); } if(tracking_id == agent_id) diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 48b93fdf9d..f45adfbfec 100644 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -109,6 +109,7 @@ public: // add or remove agents from buddy list. Each method takes a set // of buddies and returns how many were actually added or removed. typedef std::map buddy_map_t; + typedef std::queue> buddy_status_queue_t; S32 addBuddyList(const buddy_map_t& buddies); //S32 removeBuddyList(const buddy_list_t& exes); @@ -194,6 +195,7 @@ protected: //LLInventoryObserver* mInventoryObserver; buddy_map_t mBuddyInfo; + buddy_status_queue_t mBuddyStatusQueue; typedef std::set changed_buddy_t; changed_buddy_t mChangedBuddyIDs; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index eb0e9ef4bc..db75e4555b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1306,6 +1306,15 @@ bool idle_startup() do_startup_frame(); do_startup_frame(); + + // It is entirely possible that we may get the friends list _before_ we have the callbacks registered to process that. + // This will lead to the friends list not being processed properly and online statuses not being updated appropriately at login. + // So, we need to make sure that we have the callbacks registered before we get the friends list. + // -Geenz 2025-03-12 + LL_INFOS() << " AvatarTracker" << LL_ENDL; + LLAvatarTracker::instance().registerCallbacks(gMessageSystem); + do_startup_frame(); + // Since we connected, save off the settings so the user doesn't have to // type the name/password again if we crash. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true); @@ -2013,8 +2022,6 @@ bool idle_startup() LLMessageSystem* msg = gMessageSystem; LL_INFOS() << " Inventory" << LL_ENDL; LLInventoryModel::registerCallbacks(msg); - LL_INFOS() << " AvatarTracker" << LL_ENDL; - LLAvatarTracker::instance().registerCallbacks(msg); LL_INFOS() << " Landmark" << LL_ENDL; LLLandmark::registerCallbacks(msg); do_startup_frame(); -- cgit v1.2.3 From 864b5a7222cc20fea82e3e2ad7fd1055ed72f552 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 13 Mar 2025 00:22:06 -0400 Subject: Move callback registration for the avatar tracker to STATE_AGENT_SEND. --- indra/newview/llstartup.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index db75e4555b..3973036cc6 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1306,15 +1306,6 @@ bool idle_startup() do_startup_frame(); do_startup_frame(); - - // It is entirely possible that we may get the friends list _before_ we have the callbacks registered to process that. - // This will lead to the friends list not being processed properly and online statuses not being updated appropriately at login. - // So, we need to make sure that we have the callbacks registered before we get the friends list. - // -Geenz 2025-03-12 - LL_INFOS() << " AvatarTracker" << LL_ENDL; - LLAvatarTracker::instance().registerCallbacks(gMessageSystem); - do_startup_frame(); - // Since we connected, save off the settings so the user doesn't have to // type the name/password again if we crash. gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), true); @@ -1723,6 +1714,15 @@ bool idle_startup() gAssetStorage->setUpstream(regionp->getHost()); gCacheName->setUpstream(regionp->getHost()); } + + // It is entirely possible that we may get the friends list _before_ we have the callbacks registered to process that. + // This will lead to the friends list not being processed properly and online statuses not being updated appropriately at login. + // So, we need to make sure that we have the callbacks registered before we get the friends list. + // This appears to crop up on some systems somewhere between STATE_AGENT_SEND and STATE_INVENTORY_SEND. It's happened to me a few times now. + // -Geenz 2025-03-12 + LL_INFOS() << " AvatarTracker" << LL_ENDL; + LLAvatarTracker::instance().registerCallbacks(gMessageSystem); + do_startup_frame(); // Create login effect -- cgit v1.2.3