From 76dd17168a6ec7f588a862b9575995687cd49b0f Mon Sep 17 00:00:00 2001
From: James Cook <james@lindenlab.com>
Date: Mon, 28 Sep 2009 23:11:18 +0000
Subject: [PATCH] DEV-40528 Viewer 2 floods server with AvatarPropertiesRequest
 messages causing database load.  Icon cache was only being used to provide
 images more quickly, not to suppress network traffic.  Made it suppress
 network traffic, which may result in stale icons occasionally.  Converted
 online/offline tooltip to use LLAvatarTracker.  Will port to viewer-2-qa-1. 
 Reviewed with Richard.

---
 indra/newview/llavatariconctrl.cpp | 52 ++++++++++++++++++++++--------
 indra/newview/llcallingcard.cpp    |  6 ++++
 indra/newview/llcallingcard.h      |  3 ++
 3 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index a8b1ff6c920..1d5fa9ffa7e 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -32,9 +32,10 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llavatariconctrl.h"
+
 #include "llagent.h"
 #include "llavatarconstants.h"
-#include "llavatariconctrl.h"
 #include "llcallingcard.h" // for LLAvatarTracker
 #include "llavataractions.h"
 #include "llimview.h"
@@ -139,25 +140,37 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
 {
 	if (value.isUUID())
 	{
+		LLAvatarPropertiesProcessor* app =
+			LLAvatarPropertiesProcessor::getInstance();
 		if (mAvatarId.notNull())
 		{
-			LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
+			app->removeObserver(mAvatarId, this);
 		}
 
 		if (mAvatarId != value.asUUID())
 		{
-			LLAvatarPropertiesProcessor::getInstance()->addObserver(value.asUUID(), this);
-			LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(value.asUUID());
 			mAvatarId = value.asUUID();
 
-			// Check if cache already contains image_id for that avatar
-			avatar_image_map_t::iterator it;
+			// *BUG: This will return stale icons if a user changes their
+			// profile picture.  Also, the online/offline tooltips will be
+			// out of date.  However, otherwise we send too many upstream
+			// AvatarPropertiesRequest messages.
+			//
+			// *TODO: Implement a timeout on the icon cache, perhaps a day?,
+			// and make the cache update if a user views the full-profile for
+			// an avatar.
 
-			it = sImagesCache.find(mAvatarId);
+			// Check if cache already contains image_id for that avatar
+			avatar_image_map_t::iterator it = sImagesCache.find(mAvatarId);
 			if (it != sImagesCache.end())
 			{
 				updateFromCache(it->second);
 			}
+			else
+			{
+				app->addObserver(value.asUUID(), this);
+				app->sendAvatarPropertiesRequest(value.asUUID());
+			}
 		}
 
 	}
@@ -181,21 +194,34 @@ void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data)
 		LLIconCtrl::setValue("default_profile_picture.j2c");
 	}
 
-	// Update color of status symbol and tool tip
-	if (data.flags & AVATAR_ONLINE)
+	// Can only see online status of friends
+	if (LLAvatarTracker::instance().isBuddy(mAvatarId))
 	{
-		mStatusSymbol->setColor(LLColor4::green);
-		if (mDrawTooltip)
+		if (LLAvatarTracker::instance().isBuddyOnline(mAvatarId))
 		{
-			setToolTip((LLStringExplicit)"Online");
+			// Update color of status symbol and tool tip
+			mStatusSymbol->setColor(LLColor4::green);
+			if (mDrawTooltip)
+			{
+				setToolTip((LLStringExplicit)"Online");
+			}
+		}
+		else
+		{
+			mStatusSymbol->setColor(LLColor4::grey);
+			if (mDrawTooltip)
+			{
+				setToolTip((LLStringExplicit)"Offline");
+			}
 		}
 	}
 	else
 	{
+		// Not a buddy, no information
 		mStatusSymbol->setColor(LLColor4::grey);
 		if (mDrawTooltip)
 		{
-			setToolTip((LLStringExplicit)"Offline");
+			setToolTip((LLStringExplicit)"");
 		}
 	}
 }
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 7326e39af3a..e3440ee7792 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -320,6 +320,12 @@ const LLRelationship* LLAvatarTracker::getBuddyInfo(const LLUUID& id) const
 	return get_ptr_in_map(mBuddyInfo, id);
 }
 
+bool LLAvatarTracker::isBuddy(const LLUUID& id) const
+{
+	LLRelationship* info = get_ptr_in_map(mBuddyInfo, id);
+	return (info != NULL);
+}
+
 // online status
 void LLAvatarTracker::setBuddyOnline(const LLUUID& id, bool is_online)
 {
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 113f16de701..228239b5ba5 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -125,6 +125,9 @@ class LLAvatarTracker
 	// get full info
 	const LLRelationship* getBuddyInfo(const LLUUID& id) const;
 
+	// Is this person a friend/buddy/calling card holder?
+	bool isBuddy(const LLUUID& id) const;
+
 	// online status
 	void setBuddyOnline(const LLUUID& id, bool is_online);
 	bool isBuddyOnline(const LLUUID& id) const;
-- 
GitLab