summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llavatarname.cpp75
-rw-r--r--indra/llcommon/llavatarname.h13
-rw-r--r--indra/llmessage/llavatarnamecache.cpp170
-rw-r--r--indra/llmessage/llavatarnamecache.h32
-rw-r--r--indra/llmessage/llcachename.h2
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp5
-rwxr-xr-xindra/newview/app_settings/settings.xml11
-rwxr-xr-xindra/newview/llstartup.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp2
9 files changed, 154 insertions, 158 deletions
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index b49e6a7aac..95ecce509b 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -45,6 +45,12 @@ static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
bool LLAvatarName::sUseDisplayNames = true;
+// Minimum time-to-live (in seconds) for a name entry.
+// Avatar name should always guarantee to expire reasonably soon by default
+// so if the failure to get a valid expiration time was due to something temporary
+// we will eventually request and get the right data.
+const F64 MIN_ENTRY_LIFETIME = 60.0;
+
LLAvatarName::LLAvatarName()
: mUsername(),
mDisplayName(),
@@ -107,40 +113,67 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
}
}
-void LLAvatarName::fromString(const std::string& full_name, F64 expires)
+// Transform a string (typically provided by the legacy service) into a decent
+// avatar name instance.
+void LLAvatarName::fromString(const std::string& full_name)
{
mDisplayName = full_name;
std::string::size_type index = full_name.find(' ');
if (index != std::string::npos)
{
+ // The name is in 2 parts (first last)
mLegacyFirstName = full_name.substr(0, index);
mLegacyLastName = full_name.substr(index+1);
- mUsername = mLegacyFirstName + " " + mLegacyLastName;
+ if (mLegacyLastName != "Resident")
+ {
+ mUsername = mLegacyFirstName + "." + mLegacyLastName;
+ mDisplayName = full_name;
+ LLStringUtil::toLower(mUsername);
+ }
+ else
+ {
+ // Very old names do have a dummy "Resident" last name
+ // that we choose to hide from users.
+ mUsername = mLegacyFirstName;
+ mDisplayName = mLegacyFirstName;
+ }
}
else
{
mLegacyFirstName = full_name;
mLegacyLastName = "";
mUsername = full_name;
+ mDisplayName = full_name;
}
mIsDisplayNameDefault = true;
mIsTemporaryName = true;
+ setExpires(MIN_ENTRY_LIFETIME);
+}
+
+void LLAvatarName::setExpires(F64 expires)
+{
mExpires = LLFrameTimer::getTotalSeconds() + expires;
}
std::string LLAvatarName::getCompleteName() const
{
std::string name;
- if (mUsername.empty() || mIsDisplayNameDefault)
- // If the display name feature is off
- // OR this particular display name is defaulted (i.e. based on user name),
- // then display only the easier to read instance of the person's name.
+ if (sUseDisplayNames)
{
- name = mDisplayName;
+ if (mUsername.empty() || mIsDisplayNameDefault)
+ {
+ // If this particular display name is defaulted (i.e. based on user name),
+ // then display only the easier to read instance of the person's name.
+ name = mDisplayName;
+ }
+ else
+ {
+ name = mDisplayName + " (" + mUsername + ")";
+ }
}
else
{
- name = mDisplayName + " (" + mUsername + ")";
+ name = getUserName();
}
return name;
}
@@ -159,23 +192,29 @@ std::string LLAvatarName::getDisplayName() const
std::string LLAvatarName::getUserName() const
{
- // If we cannot create a user name from the legacy strings, use the display name
- if (mLegacyFirstName.empty() && mLegacyLastName.empty())
+ std::string name;
+ if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
{
- return mDisplayName;
+ if (mLegacyFirstName.empty())
+ {
+ // If we cannot create a user name from the legacy strings, use the display name
+ name = mDisplayName;
+ }
+ else
+ {
+ // The last name might be empty if it defaulted to "Resident"
+ name = mLegacyFirstName;
+ }
+ }
+ else
+ {
+ name = mLegacyFirstName + " " + mLegacyLastName;
}
-
- std::string name;
- name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() );
- name = mLegacyFirstName;
- name += " ";
- name += mLegacyLastName;
return name;
}
void LLAvatarName::dump() const
{
- llinfos << "Merov debug : display = " << mDisplayName << ", user = " << mUsername << ", complete = " << getCompleteName() << ", legacy = " << getUserName() << " first = " << mLegacyFirstName << " last = " << mLegacyLastName << llendl;
LL_DEBUGS("AvNameCache") << "LLAvatarName: "
<< "user '" << mUsername << "' "
<< "display '" << mDisplayName << "' "
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index cf9eb27b03..2f8c534974 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,20 +39,25 @@ public:
bool operator<(const LLAvatarName& rhs) const;
+ // Conversion to and from LLSD (cache file or server response)
LLSD asLLSD() const;
-
void fromLLSD(const LLSD& sd);
// Used only in legacy mode when the display name capability is not provided server side
- void fromString(const std::string& full_name, F64 expires = 0.0f);
+ // or to otherwise create a temporary valid item.
+ void fromString(const std::string& full_name);
+ // Set the name object to become invalid in "expires" seconds from now
+ void setExpires(F64 expires);
+
+ // Set and get the display name flag set by the user in preferences.
static void setUseDisplayNames(bool use);
static bool useDisplayNames();
- // Name is valid if not temporary and not yet expired
+ // A name object is valid if not temporary and not yet expired (default is expiration not checked)
bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
- //
+ // Return true if the name is made up from legacy or temporary data
bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
// For normal names, returns "James Linden (james.linden)"
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 329871d8eb..15c4f2a207 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -47,18 +47,22 @@ namespace LLAvatarNameCache
// current region supports display names.
bool sRunning = false;
+ // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
+ // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
+ bool sUsePeopleAPI = true;
+
// Base lookup URL for name service.
// On simulator, loaded from indra.xml
// On viewer, usually a simulator capability (at People API team's request)
// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
std::string sNameLookupURL;
- // accumulated agent IDs for next query against service
+ // Accumulated agent IDs for next query against service
typedef std::set<LLUUID> ask_queue_t;
ask_queue_t sAskQueue;
- // agent IDs that have been requested, but with no reply
- // maps agent ID to frame time request was made
+ // Agent IDs that have been requested, but with no reply.
+ // Maps agent ID to frame time request was made.
typedef std::map<LLUUID, F64> pending_queue_t;
pending_queue_t sPendingQueue;
@@ -69,21 +73,21 @@ namespace LLAvatarNameCache
typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
signal_map_t sSignalMap;
- // names we know about
+ // The cache at last, i.e. avatar names we know about.
typedef std::map<LLUUID, LLAvatarName> cache_t;
cache_t sCache;
- // Send bulk lookup requests a few times a second at most
- // only need per-frame timing resolution
+ // Send bulk lookup requests a few times a second at most.
+ // Only need per-frame timing resolution.
LLFrameTimer sRequestTimer;
- /// Maximum time an unrefreshed cache entry is allowed
+ // Maximum time an unrefreshed cache entry is allowed.
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
- /// Time when unrefreshed cached names were checked last
+ // Time when unrefreshed cached names were checked last.
static F64 sLastExpireCheck;
- /// Time-to-live for a temp cache entry.
+ // Time-to-live for a temp cache entry.
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
//-----------------------------------------------------------------------
@@ -91,26 +95,18 @@ namespace LLAvatarNameCache
//-----------------------------------------------------------------------
// Handle name response off network.
- // Optionally skip adding to cache, used when this is a fallback to the
- // legacy name system.
void processName(const LLUUID& agent_id,
- const LLAvatarName& av_name,
- bool add_to_cache);
+ const LLAvatarName& av_name);
void requestNamesViaCapability();
// Legacy name system callback
void legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
- bool is_group
- );
+ bool is_group);
void requestNamesViaLegacy();
- // Fill in an LLAvatarName with the legacy name data
- void buildLegacyName(const std::string& full_name,
- LLAvatarName* av_name);
-
// Do a single callback to a given slot
void fireSignal(const LLUUID& agent_id,
const callback_slot_t& slot,
@@ -209,7 +205,7 @@ public:
av_name.dump();
// cache it and fire signals
- LLAvatarNameCache::processName(agent_id, av_name, true);
+ LLAvatarNameCache::processName(agent_id, av_name);
}
// Same logic as error response case
@@ -271,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
}
else
{
- // we have a chached (but probably expired) entry - since that would have
+ // we have a cached (but probably expired) entry - since that would have
// been returned by the get method, there is no need to signal anyone
// Clear this agent from the pending list
@@ -281,22 +277,20 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
av_name.dump();
- av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
+ // Reset expiry time so we don't constantly rerequest.
+ av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME);
}
}
-void LLAvatarNameCache::processName(const LLUUID& agent_id,
- const LLAvatarName& av_name,
- bool add_to_cache)
+void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- if (add_to_cache)
- {
- sCache[agent_id] = av_name;
- }
+ // Add to the cache
+ sCache[agent_id] = av_name;
+ // Suppress request from the queue
sPendingQueue.erase(agent_id);
- // signal everyone waiting on this name
+ // Signal everyone waiting on this name
signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
if (sig_it != sSignalMap.end())
{
@@ -373,22 +367,20 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group)
{
- // Construct a dummy record for this name. By convention, SLID is blank
- // Never expires, but not written to disk, so lasts until end of session.
- LLAvatarName av_name;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
<< "agent " << agent_id << " "
<< "full name '" << full_name << "'"
<< ( is_group ? " [group]" : "" )
<< LL_ENDL;
- buildLegacyName(full_name, &av_name);
+
+ // Construct an av_name record from this name.
+ LLAvatarName av_name;
+ av_name.fromString(full_name);
+ av_name.dump();
// Add to cache, because if we don't we'll keep rerequesting the
- // same record forever. buildLegacyName should always guarantee
- // that these records expire reasonably soon
- // (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
- // to something temporary we will eventually request and get the right data.
- processName(agent_id, av_name, true);
+ // same record forever.
+ processName(agent_id, av_name);
}
void LLAvatarNameCache::requestNamesViaLegacy()
@@ -410,18 +402,19 @@ void LLAvatarNameCache::requestNamesViaLegacy()
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
gCacheName->get(agent_id, false, // legacy compatibility
- boost::bind(&LLAvatarNameCache::legacyNameCallback,
- _1, _2, _3));
+ boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3));
}
}
-void LLAvatarNameCache::initClass(bool running)
+void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
{
sRunning = running;
+ sUsePeopleAPI = usePeopleAPI;
}
void LLAvatarNameCache::cleanupClass()
{
+ sCache.clear();
}
void LLAvatarNameCache::importFile(std::istream& istr)
@@ -481,6 +474,11 @@ bool LLAvatarNameCache::hasNameLookupURL()
return !sNameLookupURL.empty();
}
+bool LLAvatarNameCache::usePeopleAPI()
+{
+ return hasNameLookupURL() && sUsePeopleAPI;
+}
+
void LLAvatarNameCache::idle()
{
// By convention, start running at first idle() call
@@ -497,13 +495,12 @@ void LLAvatarNameCache::idle()
if (!sAskQueue.empty())
{
- if (hasNameLookupURL())
+ if (usePeopleAPI())
{
requestNamesViaCapability();
}
else
{
- // ...fall back to legacy name cache system
requestNamesViaLegacy();
}
}
@@ -563,18 +560,6 @@ void LLAvatarNameCache::eraseUnrefreshed()
}
}
-void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
- LLAvatarName* av_name)
-{
- llassert(av_name);
- av_name->fromString(full_name,TEMP_CACHE_ENTRY_LIFETIME);
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
- << full_name
- << LL_ENDL;
- // DEBUG ONLY!!! DO NOT COMMIT!!!
- av_name->dump();
-}
-
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
// returns bool specifying if av_name was filled, false otherwise
bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
@@ -582,38 +567,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
if (sRunning)
{
// ...only do immediate lookups when cache is running
- if (hasNameLookupURL())
+ std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+ if (it != sCache.end())
{
- // ...use display names cache
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
- {
- *av_name = it->second;
+ *av_name = it->second;
- // re-request name if entry is expired
- if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+ // re-request name if entry is expired
+ if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+ {
+ if (!isRequestPending(agent_id))
{
- if (!isRequestPending(agent_id))
- {
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
- << "refresh agent " << agent_id
- << LL_ENDL;
- sAskQueue.insert(agent_id);
- }
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
+ << "refresh agent " << agent_id
+ << LL_ENDL;
+ sAskQueue.insert(agent_id);
}
-
- return true;
- }
- }
- else
- {
- // ...use legacy names cache
- std::string full_name;
- if (gCacheName->getFullName(agent_id, full_name))
- {
- buildLegacyName(full_name, av_name);
- return true;
}
+
+ return true;
}
}
@@ -644,30 +615,14 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
if (sRunning)
{
// ...only do immediate lookups when cache is running
- if (hasNameLookupURL())
- {
- // ...use new cache
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
- {
- const LLAvatarName& av_name = it->second;
-
- if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
- {
- // ...name already exists in cache, fire callback now
- fireSignal(agent_id, slot, av_name);
- return connection;
- }
- }
- }
- else
+ std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+ if (it != sCache.end())
{
- // ...use old name system
- std::string full_name;
- if (gCacheName->getFullName(agent_id, full_name))
+ const LLAvatarName& av_name = it->second;
+
+ if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
{
- LLAvatarName av_name;
- buildLegacyName(full_name, &av_name);
+ // ...name already exists in cache, fire callback now
fireSignal(agent_id, slot, av_name);
return connection;
}
@@ -709,11 +664,6 @@ void LLAvatarNameCache::setUseDisplayNames(bool use)
}
}
-void LLAvatarNameCache::flushCache()
-{
- sCache.clear();
-}
-
void LLAvatarNameCache::erase(const LLUUID& agent_id)
{
sCache.erase(agent_id);
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index e172601432..2a8eb46187 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -37,33 +37,33 @@ class LLUUID;
namespace LLAvatarNameCache
{
-
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
// Until the cache is set running, immediate lookups will fail and
// async lookups will be queued. This allows us to block requests
// until we know if the first region supports display names.
- void initClass(bool running);
+ void initClass(bool running, bool usePeopleAPI);
void cleanupClass();
+ // Import/export the name cache to file.
void importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
- // On the viewer, usually a simulator capabilitity
- // If empty, name cache will fall back to using legacy name
- // lookup system
+ // On the viewer, usually a simulator capabilitity.
+ // If empty, name cache will fall back to using legacy name lookup system.
void setNameLookupURL(const std::string& name_lookup_url);
- // Do we have a valid lookup URL, hence are we trying to use the
- // new display name lookup system?
+ // Do we have a valid lookup URL, i.e. are we trying to use the
+ // more recent display name lookup system?
bool hasNameLookupURL();
+ bool usePeopleAPI();
// Periodically makes a batch request for display names not already in
- // cache. Call once per frame.
+ // cache. Called once per frame.
void idle();
// If name is in cache, returns true and fills in provided LLAvatarName
- // otherwise returns false
+ // otherwise returns false.
bool get(const LLUUID& agent_id, LLAvatarName *av_name);
// Callback types for get() below
@@ -73,23 +73,19 @@ namespace LLAvatarNameCache
typedef callback_signal_t::slot_type callback_slot_t;
typedef boost::signals2::connection callback_connection_t;
- // Fetches name information and calls callback.
- // If name information is in cache, callback will be called immediately.
+ // Fetches name information and calls callbacks.
+ // If name information is in cache, callbacks will be called immediately.
callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
- // Allow display names to be explicitly disabled for testing.
+ // Set display name: flips the switch and triggers the callbacks.
void setUseDisplayNames(bool use);
- bool useDisplayNames();
-
- void flushCache();
+ void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
void erase(const LLUUID& agent_id);
- /// Provide some fallback for agents that return errors
+ /// Provide some fallback for agents that return errors.
void handleAgentError(const LLUUID& agent_id);
- void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
-
// Compute name expiration time from HTTP Cache-Control header,
// or return default value, in seconds from epoch.
F64 nameExpirationFromHeaders(LLSD headers);
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index b108e37157..d238c3a247 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -40,7 +40,7 @@ typedef boost::signals2::signal<void (const LLUUID& id,
bool is_group)> LLCacheNameSignal;
typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
-// Old callback with user data for compatability
+// Old callback with user data for compatibility
typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
// Here's the theory:
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index f8797fd257..5d3f9ac327 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -46,11 +46,6 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
return connection;
}
-bool LLAvatarNameCache::useDisplayNames()
-{
- return false;
-}
-
//
// Stub implementation for LLCacheName
//
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ece711a128..423e5a00df 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12648,6 +12648,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UsePeopleAPI</key>
+ <map>
+ <key>Comment</key>
+ <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>UseStartScreen</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 34259658ea..66a2e6dbda 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2806,7 +2806,7 @@ void LLStartUp::initNameCache()
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
- LLAvatarNameCache::initClass(false);
+ LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5284d2650e..7ae717cb42 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8080,7 +8080,7 @@ class LLWorldPostProcess : public view_listener_t
void handle_flush_name_caches()
{
- LLAvatarNameCache::flushCache();
+ LLAvatarNameCache::cleanupClass();
if (gCacheName) gCacheName->clear();
}