From c16591c046fa76fc5d13387efa3bcaec3422e593 Mon Sep 17 00:00:00 2001 From: James Cook Date: Fri, 12 Feb 2010 16:12:12 -0800 Subject: Per-avatar customizable icons next to name links in text Changed LLUrlEntryAgent callbacks to handle both link label and icon Eliminated legacy LLNameCache file loading Reviewed with Kelly --- indra/newview/llappviewer.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 00a9e4d745..ba2e13da9d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1298,8 +1298,7 @@ bool LLAppViewer::cleanup() LLPolyMesh::freeAllMeshes(); - delete gCacheName; - gCacheName = NULL; + LLStartUp::cleanupNameCache(); // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. @@ -3337,15 +3336,6 @@ void LLAppViewer::loadNameCache() { if(gCacheName->importFile(cache_file)) return; } - - // Try to load from the legacy format. This should go away after a - // while. Phoenix 2008-01-30 - LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore - if (name_cache_fp) - { - gCacheName->importFile(name_cache_fp); - fclose(name_cache_fp); - } } void LLAppViewer::saveNameCache() -- cgit v1.3 From 55bfb4435e1a2ffc34578bf30877eb24a5edaa29 Mon Sep 17 00:00:00 2001 From: James Cook Date: Wed, 17 Feb 2010 16:55:58 -0800 Subject: Look up display names via a web service Also removed unused LLComboBox globals to reduce llappviewer.cpp include file burden. Review pending --- indra/llmessage/llavatarnamecache.cpp | 212 ++++++++++++++++++++++++++++------ indra/llmessage/llavatarnamecache.h | 2 + indra/llui/llcombobox.cpp | 2 - indra/llui/llcombobox.h | 3 - indra/newview/llappviewer.cpp | 7 +- 5 files changed, 180 insertions(+), 46 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index dbcb0d0c03..a7ed20ac9b 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -35,15 +35,92 @@ #include "llavatarnamecache.h" #include "llcachename.h" // until we get our own web service +#include "llframetimer.h" +#include "llhttpclient.h" +#include "llsdserialize.h" // JAMESDEBUG #include // tolower() +#include namespace LLAvatarNameCache { - std::map sCache; + // base URL for name lookup service + std::string sNameServiceURL; + + // accumulated agent IDs for next query against service + typedef std::set 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 + typedef std::map pending_queue_t; + pending_queue_t sPendingQueue; + + // names we know about + typedef std::map cache_t; + cache_t sCache; + + // only need per-frame timing resolution + LLFrameTimer sRequestTimer; + + bool isRequestPending(const LLUUID& agent_id); } -// JAMESDEBUG re-enable when display names are turned on +class LLAvatarNameResponder : public LLHTTPClient::Responder +{ +public: + /*virtual*/ void result(const LLSD& content); + /*virtual*/ void error(U32 status, const std::string& reason); +}; + +void LLAvatarNameResponder::result(const LLSD& content) +{ + //std::ostringstream debug; + //LLSDSerialize::toPrettyXML(content, debug); + //llinfos << "JAMESDEBUG " << debug.str() << llendl; + + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + LLSD::array_const_iterator it = content.beginArray(); + for ( ; it != content.endArray(); ++it) + { + const LLSD& row = *it; + + LLAvatarName av_name; + av_name.mSLID = row["slid"]; + av_name.mDisplayName = row["display_name"]; + av_name.mLastUpdate = now; + + // HACK for pretty stars + if (row["last_name"].asString() == "Linden") + { + av_name.mBadge = "Person_Star"; + } + + // Some avatars don't have explicit display names set + if (av_name.mDisplayName.empty()) + { + // make up a display name + std::string first_name = row["first_name"]; + std::string last_name = row["last_name"]; + av_name.mDisplayName = + LLCacheName::buildFullName(first_name, last_name); + } + + LLUUID agent_id = row["agent_id"]; + LLAvatarNameCache::sCache[agent_id] = av_name; + + LLAvatarNameCache::sPendingQueue.erase(agent_id); + + llinfos << "JAMESDEBUG fetched " << av_name.mDisplayName << llendl; + } +} + +void LLAvatarNameResponder::error(U32 status, const std::string& reason) +{ + llinfos << "JAMESDEBUG error " << status << " " << reason << llendl; +} + +// JAMESDEBUG re-enable when display names are turned on??? //static std::string slid_from_full_name(const std::string& full_name) //{ // std::string id = full_name; @@ -73,11 +150,6 @@ void LLAvatarNameCache::initClass() name.mBadge = "Person_Check"; sCache[LLUUID("27888d5f-4ddb-4df3-ad36-a1483ce0b3d9")] = name; - name.mSLID = "jim.linden"; - name.mDisplayName = "Jim Jenkins"; - name.mBadge = "Person_Star"; - sCache[LLUUID("3e5bf676-3577-c9ee-9fac-10df430015a1")] = name; - name.mSLID = "james.linden"; const unsigned char jose_sanchez[] = { 'J','o','s',0xC3,0xA9,' ','S','a','n','c','h','e','z', '\0' }; @@ -90,35 +162,41 @@ void LLAvatarNameCache::initClass() name.mBadge = ""; sCache[LLUUID("a23fff6c-80ae-4997-9253-48272fd01d3c")] = name; - name.mSLID = "hamilton.linden"; - name.mDisplayName = "Hamilton Hitchings"; - name.mBadge = "Person_Star"; - sCache[LLUUID("3f7ced39-5e38-4fdd-90f2-423560b1e6e2")] = name; - - name.mSLID = "rome.linden"; - name.mDisplayName = "Rome Portlock"; - name.mBadge = "Person_Star"; - sCache[LLUUID("537da1e1-a89f-4f9b-9056-b1f0757ccdd0")] = name; - - name.mSLID = "m.linden"; - name.mDisplayName = "Mark Kingdon"; - name.mBadge = "Person_Star"; - sCache[LLUUID("244195d6-c9b7-4fd6-9229-c3a8b2e60e81")] = name; - - name.mSLID = "t.linden"; - name.mDisplayName = "Tom Hale"; - name.mBadge = "Person_Star"; - sCache[LLUUID("49856302-98d4-4e32-b5e9-035e5b4e83a4")] = name; - - name.mSLID = "callen.linden"; - name.mDisplayName = "Christina Allen"; - name.mBadge = "Person_Star"; - sCache[LLUUID("e6ed7825-708f-4c6b-b6a7-f3fe921a9176")] = name; - - name.mSLID = "crimp.linden"; - name.mDisplayName = "Chris Rimple"; - name.mBadge = "Person_Star"; - sCache[LLUUID("a7f0ac18-205f-41d2-b5b4-f75f096ae511")] = name; + // These are served by the web service now + //name.mSLID = "jim.linden"; + //name.mDisplayName = "Jim Jenkins"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("3e5bf676-3577-c9ee-9fac-10df430015a1")] = name; + + //name.mSLID = "hamilton.linden"; + //name.mDisplayName = "Hamilton Hitchings"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("3f7ced39-5e38-4fdd-90f2-423560b1e6e2")] = name; + + //name.mSLID = "rome.linden"; + //name.mDisplayName = "Rome Portlock"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("537da1e1-a89f-4f9b-9056-b1f0757ccdd0")] = name; + + //name.mSLID = "m.linden"; + //name.mDisplayName = "Mark Kingdon"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("244195d6-c9b7-4fd6-9229-c3a8b2e60e81")] = name; + + //name.mSLID = "t.linden"; + //name.mDisplayName = "Tom Hale"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("49856302-98d4-4e32-b5e9-035e5b4e83a4")] = name; + + //name.mSLID = "callen.linden"; + //name.mDisplayName = "Christina Allen"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("e6ed7825-708f-4c6b-b6a7-f3fe921a9176")] = name; + + //name.mSLID = "crimp.linden"; + //name.mDisplayName = "Chris Rimple"; + //name.mBadge = "Person_Star"; + //sCache[LLUUID("a7f0ac18-205f-41d2-b5b4-f75f096ae511")] = name; } void LLAvatarNameCache::cleanupClass() @@ -135,6 +213,57 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr) void LLAvatarNameCache::idle() { + const F32 SECS_BETWEEN_REQUESTS = 0.5f; // JAMESDEBUG set to 0.1? + if (sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) + { + return; + } + + if (sAskQueue.empty()) + { + return; + } + + LLSD body; + body["agent_ids"] = LLSD::emptyArray(); + LLSD& agent_ids = body["agent_ids"]; + + ask_queue_t::const_iterator it = sAskQueue.begin(); + for ( ; it != sAskQueue.end(); ++it) + { + agent_ids.append( LLSD( *it ) ); + } + + //std::ostringstream debug; + //LLSDSerialize::toPrettyXML(body, debug); + //LL_INFOS("JAMESDEBUG") << debug.str() << LL_ENDL; + + // *TODO: configure the base URL for this + std::string url = "http://pdp15.lindenlab.com:8050/my-service/agent/display-names/"; + LLHTTPClient::post(url, body, new LLAvatarNameResponder()); + + // Move requests from Ask queue to Pending queue + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + for (it = sAskQueue.begin(); it != sAskQueue.end(); ++it) + { + sPendingQueue[*it] = now; + } + sAskQueue.clear(); +} + +bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id) +{ + const U32 PENDING_TIMEOUT_SECS = 5 * 60; + U32 now = (U32)LLFrameTimer::getTotalSeconds(); + U32 expire_time = now - PENDING_TIMEOUT_SECS; + + pending_queue_t::const_iterator it = sPendingQueue.find(agent_id); + if (it != sPendingQueue.end()) + { + bool expired = (it->second < expire_time); + return !expired; + } + return false; } bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) @@ -146,7 +275,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) return true; } - // JAMESDEBUG Enable when we turn on display names. + // JAMESDEBUG Enable when we turn on display names??? //std::string full_name; //if (gCacheName->getFullName(agent_id, full_name)) //{ @@ -156,6 +285,15 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) // return true; //} + if (!isRequestPending(agent_id)) + { + std::pair found = sAskQueue.insert(agent_id); + if (found.second) + { + LL_INFOS("JAMESDEBUG") << "added to ask queue " << agent_id << LL_ENDL; + } + } + return false; } diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index adf12bbbc6..a0e6abf303 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -43,6 +43,8 @@ namespace LLAvatarNameCache void importFile(std::istream& istr); void exportFile(std::ostream& ostr); + // Periodically makes a batch request for display names not already in + // cache. Call once per frame. void idle(); // If name is in cache, returns true and fills in provided LLAvatarName diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 9d23daf56d..1aa44f6b96 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -58,8 +58,6 @@ #include "lltooltip.h" // Globals -S32 LLCOMBOBOX_HEIGHT = 0; -S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; static LLDefaultChildRegistry::Register register_combo_box("combo_box"); diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 4f27588467..58e29dcb30 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -49,9 +49,6 @@ class LLFontGL; class LLViewBorder; -extern S32 LLCOMBOBOX_HEIGHT; -extern S32 LLCOMBOBOX_WIDTH; - class LLComboBox : public LLUICtrl, public LLCtrlListInterface { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ba2e13da9d..62b8b972b6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -85,6 +85,7 @@ #include "llsecondlifeurls.h" // Linden library includes +#include "llavatarnamecache.h" #include "llimagej2c.h" #include "llmemory.h" #include "llprimitive.h" @@ -157,7 +158,6 @@ // Included so that constants/settings might be initialized // in save_settings_to_globals() #include "llbutton.h" -#include "llcombobox.h" #include "llstatusbar.h" #include "llsurface.h" #include "llvosky.h" @@ -399,9 +399,6 @@ static void settings_to_globals() MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight"); MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); - LLCOMBOBOX_HEIGHT = BTN_HEIGHT - 2; - LLCOMBOBOX_WIDTH = 128; - LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); @@ -3897,6 +3894,8 @@ void LLAppViewer::idleNetwork() // deal with any queued name requests and replies. gCacheName->processPending(); + LLAvatarNameCache::idle(); + llpushcallstacks ; LLTimer check_message_timer; // Read all available packets from network -- cgit v1.3 From d38727e47ba5d7dd449c6ba62ac6c988ac66236f Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 19 Apr 2010 11:26:30 -0700 Subject: DEV-47529 Viewer refresh name lookup cap URL on region cross/teleport Reviewed with Kelly --- indra/newview/llappviewer.cpp | 42 +++++++++++++++++++++++++++++++++++----- indra/newview/llappviewer.h | 2 ++ indra/newview/llviewerregion.cpp | 18 ----------------- 3 files changed, 39 insertions(+), 23 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 02902bc8a5..409146c4a3 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3541,9 +3541,10 @@ void LLAppViewer::idle() // NOTE: Starting at this point, we may still have pointers to "dead" objects // floating throughout the various object lists. // + idleNameCache(); idleNetwork(); - + // Check for away from keyboard, kick idle agents. idle_afk_check(); @@ -3878,6 +3879,41 @@ void LLAppViewer::sendLogoutRequest() } } +void LLAppViewer::idleNameCache() +{ + // Neither old nor new name cache can function before agent has a region + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + // deal with any queued name requests and replies. + gCacheName->processPending(); + + // Agent may have moved to a different region, so need to update cap URL + // for name lookups. Can't do this in the cap grant code, as caps are + // granted to neighbor regions before the main agent gets there. Can't + // do it in the move-into-region code because cap not guaranteed to be + // granted yet, for example on teleport. + std::string name_lookup_url; + name_lookup_url.reserve(128); // avoid a memory allocation below + name_lookup_url = region->getCapability("GetDisplayNames"); + + // Ensure capability has been granted + U32 url_size = name_lookup_url.size(); + if (url_size > 0) + { + // capabilities require URLs with slashes before query params: + // https://:/cap//?ids= + // but the caps are granted like: + // https://:/cap/ + if (name_lookup_url[url_size-1] != '/') + { + name_lookup_url += '/'; + } + LLAvatarNameCache::setNameLookupURL(name_lookup_url); + } + LLAvatarNameCache::idle(); +} + // // Handle messages, and all message related stuff // @@ -3905,10 +3941,6 @@ void LLAppViewer::idleNetwork() { LLFastTimer t(FTM_IDLE_NETWORK); // decode - // deal with any queued name requests and replies. - gCacheName->processPending(); - LLAvatarNameCache::idle(); - llpushcallstacks ; LLTimer check_message_timer; // Read all available packets from network diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a915b7fa50..ff3816922e 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -210,6 +210,8 @@ private: void idle(); void idleShutdown(); + // update avatar SLID and display name caches + void idleNameCache(); void idleNetwork(); void sendLogoutRequest(); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index feade68edc..83c5760b58 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -175,24 +175,6 @@ public: mRegion->showReleaseNotes(); } } - - // JAMESDEBUG *TODO* THIS IS WRONG!!!!!!!!!!!!!!!!!!!!! - // this isn't necessarily the region the viewer is in - - // Avatar name lookup library needs to know who to ask - std::string name_lookup_url = mRegion->getCapability("GetDisplayNames"); - // capabilities require URLs with slashes before query params, like: - // https://:/cap//?ids= - // but the caps are granted like: - // https://:/cap/ - U32 url_size = name_lookup_url.size(); - if (url_size > 0 && name_lookup_url[url_size-1] != '/') - { - name_lookup_url += '/'; - } - LLAvatarNameCache::setNameLookupURL(name_lookup_url); - - llinfos << "JAMESDEBUG cap " << name_lookup_url << llendl; if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) { -- cgit v1.3 From 022a598694cd37bebff3322054324c7d27afd5ff Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 20 Apr 2010 17:05:49 -0700 Subject: Viewer caches avatar display names between sessions Reviewed with Simon --- indra/llcommon/llavatarname.cpp | 25 +++++++++++++++++++++++++ indra/llcommon/llavatarname.h | 8 +++++++- indra/llmessage/llavatarnamecache.cpp | 34 ++++++++++++++++++++++++++++++++++ indra/newview/llappviewer.cpp | 18 ++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 5debf88818..62ba7cb112 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -35,6 +35,13 @@ #include "llavatarname.h" +// Store these in pre-built std::strings to avoid memory allocations in +// LLSD map lookups +static const std::string SL_ID("sl_id"); +static const std::string DISPLAY_NAME("display_name"); +static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default"); +static const std::string EXPIRES("expires"); + LLAvatarName::LLAvatarName() : mSLID(), mDisplayName(), @@ -50,3 +57,21 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const else return mSLID < rhs.mSLID; } + +LLSD LLAvatarName::asLLSD() const +{ + LLSD sd; + sd[SL_ID] = mSLID; + sd[DISPLAY_NAME] = mDisplayName; + sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; + sd[EXPIRES] = mExpires; + return sd; +} + +void LLAvatarName::fromLLSD(const LLSD& sd) +{ + mSLID = sd[SL_ID].asString(); + mDisplayName = sd[DISPLAY_NAME].asString(); + mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); + mExpires = sd[EXPIRES].asReal(); +} diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 72e2980b5c..11bd5f30b7 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -36,13 +36,19 @@ #include +class LLSD; + class LL_COMMON_API LLAvatarName { public: LLAvatarName(); - + bool operator<(const LLAvatarName& rhs) const; + LLSD asLLSD() const; + + void fromLLSD(const LLSD& sd); + // "bobsmith123" or "james.linden", US-ASCII only std::string mSLID; diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 69770c1f2a..d10958d09d 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -37,6 +37,7 @@ #include "llframetimer.h" #include "llhttpclient.h" #include "llsd.h" +#include "llsdserialize.h" #include #include @@ -243,10 +244,43 @@ void LLAvatarNameCache::cleanupClass() void LLAvatarNameCache::importFile(std::istream& istr) { + LLSD data; + S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr); + if (parse_count < 1) return; + + // by convention LLSD storage is a map + // we only store one entry in the map + LLSD agents = data["agents"]; + + LLUUID agent_id; + LLAvatarName av_name; + LLSD::map_const_iterator it = agents.beginMap(); + for ( ; it != agents.endMap(); ++it) + { + agent_id.set(it->first); + av_name.fromLLSD( it->second ); + sCache[agent_id] = av_name; + } + // entries may have expired since we last ran the viewer, just + // clean them out now + eraseExpired(); + llinfos << "loaded " << sCache.size() << llendl; } void LLAvatarNameCache::exportFile(std::ostream& ostr) { + LLSD agents; + cache_t::const_iterator it = sCache.begin(); + for ( ; it != sCache.end(); ++it) + { + const LLUUID& agent_id = it->first; + const LLAvatarName& av_name = it->second; + // key must be a string + agents[agent_id.asString()] = av_name.asLLSD(); + } + LLSD data; + data["agents"] = agents; + LLSDSerialize::toPrettyXML(data, ostr); } void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 409146c4a3..ac9672858d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3333,6 +3333,15 @@ void LLAppViewer::saveFinalSnapshot() void LLAppViewer::loadNameCache() { + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + llifstream name_cache_stream(filename); + if(name_cache_stream.is_open()) + { + LLAvatarNameCache::importFile(name_cache_stream); + } + if (!gCacheName) return; std::string name_cache; @@ -3346,6 +3355,15 @@ void LLAppViewer::loadNameCache() void LLAppViewer::saveNameCache() { + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + llofstream name_cache_stream(filename); + if(name_cache_stream.is_open()) + { + LLAvatarNameCache::exportFile(name_cache_stream); + } + if (!gCacheName) return; std::string name_cache; -- cgit v1.3 From 98f5fc5ff006a82cacde47de0cbb564b6e703597 Mon Sep 17 00:00:00 2001 From: James Cook Date: Thu, 22 Apr 2010 14:13:45 -0700 Subject: DEV-47529 Turn off display names if no capability from simulator, and Display name update broadcasts entire new name record to nearby viewers Display name update directly inserts new name into sim cache indra.xml has display_names_enabled setting to control cap Synchronized viewer and server versions of avatar name cache Reviewed with Ambroff --- indra/llcommon/llavatarname.cpp | 10 +++++-- indra/llcommon/llavatarname.h | 2 +- indra/llmessage/llavatarnamecache.cpp | 53 ++++++++++++++++++++--------------- indra/llmessage/llavatarnamecache.h | 11 ++------ indra/newview/llappviewer.cpp | 36 +++++++++++++++--------- indra/newview/llviewerdisplayname.cpp | 14 +++++---- indra/newview/llviewerregion.cpp | 17 +++++++++-- indra/newview/llviewerregion.h | 6 ++++ 8 files changed, 93 insertions(+), 56 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 62ba7cb112..c35b8380b8 100644 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -35,12 +35,15 @@ #include "llavatarname.h" +#include "lldate.h" +#include "llsd.h" + // Store these in pre-built std::strings to avoid memory allocations in // LLSD map lookups static const std::string SL_ID("sl_id"); static const std::string DISPLAY_NAME("display_name"); static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default"); -static const std::string EXPIRES("expires"); +static const std::string DISPLAY_NAME_EXPIRES("display_name_expires"); LLAvatarName::LLAvatarName() : mSLID(), @@ -64,7 +67,7 @@ LLSD LLAvatarName::asLLSD() const sd[SL_ID] = mSLID; sd[DISPLAY_NAME] = mDisplayName; sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; - sd[EXPIRES] = mExpires; + sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires); return sd; } @@ -73,5 +76,6 @@ void LLAvatarName::fromLLSD(const LLSD& sd) mSLID = sd[SL_ID].asString(); mDisplayName = sd[DISPLAY_NAME].asString(); mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); - mExpires = sd[EXPIRES].asReal(); + LLDate expires = sd[DISPLAY_NAME_EXPIRES]; + mExpires = expires.secondsSinceEpoch(); } diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 11bd5f30b7..b30dca6e6e 100644 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -63,7 +63,7 @@ public: // Names can change, so need to keep track of when name was // last checked. - // Unix time-from-epoch seconds + // Unix time-from-epoch seconds for efficiency F64 mExpires; // Can be a viewer UI image name ("Person_Check") or a server-side diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 6455286770..72498111fd 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -48,9 +48,6 @@ namespace LLAvatarNameCache // in the middle of a session. bool sUseDisplayNames = true; - // While false, buffer requests for later. Used during viewer startup. - bool sRunning = false; - // Base lookup URL for name service. // On simulator, loaded from indra.xml // On viewer, usually a simulator capability (at People API team's request) @@ -85,7 +82,8 @@ namespace LLAvatarNameCache LLFrameTimer sEraseExpiredTimer; void processNameFromService(const LLSD& row); - void requestNames(); + void requestNamesViaCapability(); + void requestNamesViaLegacy(); bool isRequestPending(const LLUUID& agent_id); // Erase expired names from cache @@ -203,7 +201,7 @@ void LLAvatarNameCache::processNameFromService(const LLSD& row) } } -void LLAvatarNameCache::requestNames() +void LLAvatarNameCache::requestNamesViaCapability() { // URL format is like: // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 @@ -252,9 +250,13 @@ void LLAvatarNameCache::requestNames() } } -void LLAvatarNameCache::initClass(bool running) +void LLAvatarNameCache::requestNamesViaLegacy() +{ + // JAMESDEBUG TODO +} + +void LLAvatarNameCache::initClass() { - sRunning = running; } void LLAvatarNameCache::cleanupClass() @@ -307,18 +309,8 @@ void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) sNameLookupURL = name_lookup_url; } -void LLAvatarNameCache::setRunning(bool running) -{ - sRunning = running; -} - void LLAvatarNameCache::idle() { - if (!sRunning) - { - return; - } - // 100 ms is the threshold for "user speed" operations, so we can // stall for about that long to batch up requests. const F32 SECS_BETWEEN_REQUESTS = 0.1f; @@ -334,18 +326,21 @@ void LLAvatarNameCache::idle() eraseExpired(); } - if (sNameLookupURL.empty()) + if (sAskQueue.empty()) { - // ...viewer has not yet received capability from region return; } - if (sAskQueue.empty()) + if (!sNameLookupURL.empty()) { - return; + requestNamesViaCapability(); + } + else + { + // ...fall back to legacy name cache system + requestNamesViaLegacy(); + llwarns << "JAMESDEBUG legacy lookup call" << llendl; } - - requestNames(); // Move requests from Ask queue to Pending queue F64 now = LLFrameTimer::getTotalSeconds(); @@ -460,3 +455,15 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id) { sCache.erase(agent_id); } + +void LLAvatarNameCache::fetch(const LLUUID& agent_id) +{ + // re-request, even if request is already pending + sAskQueue.insert(agent_id); +} + +void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + // *TODO: update timestamp if zero? + sCache[agent_id] = av_name; +} diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 4aabacd1f3..68a6c28b7b 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -42,21 +42,16 @@ class LLUUID; namespace LLAvatarNameCache { - // On the viewer, name cache starts in a non-running state until we - // know if we have the name lookup capability for the agent's region. - // In that state it buffers requests for later. - void initClass(bool running); + void initClass(); void cleanupClass(); 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 void setNameLookupURL(const std::string& name_lookup_url); - - // Once we know if the lookup service is available we can start - // requesting names. - void setRunning(bool running); // Periodically makes a batch request for display names not already in // cache. Call once per frame. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ac9672858d..e160951b91 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3906,6 +3906,11 @@ void LLAppViewer::idleNameCache() // deal with any queued name requests and replies. gCacheName->processPending(); + // Can't run the new cache until we have the list of capabilities + // for the agent region, and can therefore decide whether to use + // display names or fall back to the old name system. + if (!region->capabilitiesReceived()) return; + // Agent may have moved to a different region, so need to update cap URL // for name lookups. Can't do this in the cap grant code, as caps are // granted to neighbor regions before the main agent gets there. Can't @@ -3914,21 +3919,26 @@ void LLAppViewer::idleNameCache() std::string name_lookup_url; name_lookup_url.reserve(128); // avoid a memory allocation below name_lookup_url = region->getCapability("GetDisplayNames"); - - // Ensure capability has been granted - U32 url_size = name_lookup_url.size(); - if (url_size > 0) - { - // capabilities require URLs with slashes before query params: - // https://:/cap//?ids= - // but the caps are granted like: - // https://:/cap/ - if (name_lookup_url[url_size-1] != '/') - { - name_lookup_url += '/'; - } + if (!name_lookup_url.empty()) + { + // we have support for display names, use it + U32 url_size = name_lookup_url.size(); + // capabilities require URLs with slashes before query params: + // https://:/cap//?ids= + // but the caps are granted like: + // https://:/cap/ + if (url_size > 0 && name_lookup_url[url_size-1] != '/') + { + name_lookup_url += '/'; + } LLAvatarNameCache::setNameLookupURL(name_lookup_url); } + else + { + // Display names not available on this region + LLAvatarNameCache::setNameLookupURL( std::string() ); + } + LLAvatarNameCache::idle(); } diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp index 1cfada48ad..8bed501c6e 100644 --- a/indra/newview/llviewerdisplayname.cpp +++ b/indra/newview/llviewerdisplayname.cpp @@ -120,20 +120,22 @@ class LLDisplayNameUpdate : public LLHTTPNode { LLSD body = input["body"]; LLUUID agent_id = body["agent_id"]; - std::string slid = body["sl_id"]; std::string old_display_name = body["old_display_name"]; - std::string new_display_name = body["new_display_name"]; + // By convention this record is called "agent" in the People API + std::string name_data = body["agent"]; - // force re-request of this agent's name data - LLAvatarNameCache::erase(agent_id); + // Inject the new name data into cache + LLAvatarName av_name; + av_name.fromLLSD( name_data ); + LLAvatarNameCache::insert(agent_id, av_name); // force name tag to update LLVOAvatar::invalidateNameTag(agent_id); LLSD args; args["OLD_NAME"] = old_display_name; - args["SLID"] = slid; - args["NEW_NAME"] = new_display_name; + args["SLID"] = av_name.mSLID; + args["NEW_NAME"] = av_name.mDisplayName; LLNotificationsUtil::add("DisplayNameUpdate", args); } }; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 502fc87e41..9e877bc1af 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -175,7 +175,9 @@ public: mRegion->showReleaseNotes(); } } - + + mRegion->setCapabilitiesReceived(true); + if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) { LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); @@ -232,7 +234,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, // LLCapabilityListener binds all the globals it expects to need at // construction time. mCapabilityListener(host.getString(), gMessageSystem, *this, - gAgent.getID(), gAgent.getSessionID()) + gAgent.getID(), gAgent.getSessionID()), + mCapabilitiesReceived(false) { mWidth = region_width_meters; mOriginGlobal = from_region_handle(handle); @@ -1557,6 +1560,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const return iter->second; } +bool LLViewerRegion::capabilitiesReceived() const +{ + return mCapabilitiesReceived; +} + +void LLViewerRegion::setCapabilitiesReceived(bool received) +{ + mCapabilitiesReceived = received; +} + void LLViewerRegion::logActiveCapabilities() const { int count = 0; diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 49d0900f2a..5f6c754187 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -232,6 +232,11 @@ public: void setCapability(const std::string& name, const std::string& url); // implements LLCapabilityProvider virtual std::string getCapability(const std::string& name) const; + + // has region received its final (not seed) capability list? + bool capabilitiesReceived() const; + void setCapabilitiesReceived(bool received); + static bool isSpecialCapabilityName(const std::string &name); void logActiveCapabilities() const; @@ -412,6 +417,7 @@ private: private: bool mAlive; // can become false if circuit disconnects + bool mCapabilitiesReceived; //spatial partitions for objects in this region std::vector mObjectPartition; -- cgit v1.3 From d89de271437f35f9d26e28409e6cc1d593a2fc7a Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 26 Apr 2010 10:51:42 -0700 Subject: DEV-47529 Viewer turns display names on/off based on region capability Also refreshes name tags so you can see the state. Reviewed with Kelly. --- indra/newview/llappviewer.cpp | 18 +++++++++++++++++- indra/newview/llvoavatar.cpp | 14 ++++++++++++++ indra/newview/llvoavatar.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e160951b91..3b236676f1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3919,7 +3919,8 @@ void LLAppViewer::idleNameCache() std::string name_lookup_url; name_lookup_url.reserve(128); // avoid a memory allocation below name_lookup_url = region->getCapability("GetDisplayNames"); - if (!name_lookup_url.empty()) + bool have_capability = !name_lookup_url.empty(); + if (have_capability) { // we have support for display names, use it U32 url_size = name_lookup_url.size(); @@ -3939,6 +3940,21 @@ void LLAppViewer::idleNameCache() LLAvatarNameCache::setNameLookupURL( std::string() ); } + // Error recovery - did we change state? + if (LLAvatarNameCache::useDisplayNames() && !have_capability) + { + // ...we just lost the capability, turn names off + LLAvatarNameCache::setUseDisplayNames(false); + // name tags are persistant on screen, so make sure they refresh + LLVOAvatar::invalidateNameTags(); + } + else if (!LLAvatarNameCache::useDisplayNames() && have_capability) + { + // ...we just gained the capability, turn names on + LLAvatarNameCache::setUseDisplayNames(true); + LLVOAvatar::invalidateNameTags(); + } + LLAvatarNameCache::idle(); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 881012467e..9e56357b30 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3017,6 +3017,20 @@ void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id) avatar->clearNameTag(); } +//static +void LLVOAvatar::invalidateNameTags() +{ + std::vector::iterator it = LLCharacter::sInstances.begin(); + for ( ; it != LLCharacter::sInstances.end(); ++it) + { + LLVOAvatar* avatar = dynamic_cast(*it); + if (!avatar) continue; + if (avatar->isDead()) continue; + + avatar->clearNameTag(); + } +} + // Compute name tag position during idle update LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 4e0275deb5..ad0e2b096e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -216,6 +216,8 @@ public: LLColor4 getNameTagColor(bool is_friend); void clearNameTag(); static void invalidateNameTag(const LLUUID& agent_id); + // force all name tags to rebuild, useful when display names turned on/off + static void invalidateNameTags(); void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderCost(); void idleUpdateTractorBeam(); -- cgit v1.3 From 56f5a6909d8a665531e3f6ede380cad57e313728 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 27 Apr 2010 13:54:40 -0700 Subject: Menu item to disable display names for testing works again Start up cache in not-running state on viewer. Set cache running when idle() is called. Explicitly refresh name tags when toggled. Reviewed with Simon --- indra/llmessage/llavatarnamecache.cpp | 50 ++++++++++++++++++++++++----------- indra/llmessage/llavatarnamecache.h | 13 ++++++--- indra/newview/llappviewer.cpp | 11 ++------ indra/newview/llstartup.cpp | 4 ++- indra/newview/llviewermenu.cpp | 2 ++ 5 files changed, 51 insertions(+), 29 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 5acecd1dcb..85775f19da 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -44,9 +44,13 @@ namespace LLAvatarNameCache { - // Will be turned on and off based on service availability, sometimes - // in the middle of a session. + // Manual override for display names - can disable even if the region + // supports it. bool sUseDisplayNames = true; + + // Cache starts in a paused state until we can determine if the + // current region supports display names. + bool sRunning = false; // Base lookup URL for name service. // On simulator, loaded from indra.xml @@ -318,8 +322,9 @@ void LLAvatarNameCache::requestNamesViaLegacy() // JAMESDEBUG TODO } -void LLAvatarNameCache::initClass() +void LLAvatarNameCache::initClass(bool running) { + sRunning = running; } void LLAvatarNameCache::cleanupClass() @@ -375,8 +380,16 @@ void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) sNameLookupURL = name_lookup_url; } +bool LLAvatarNameCache::hasNameLookupURL() +{ + return !sNameLookupURL.empty(); +} + void LLAvatarNameCache::idle() { + // By convention, start running at first idle() call + sRunning = true; + // 100 ms is the threshold for "user speed" operations, so we can // stall for about that long to batch up requests. const F32 SECS_BETWEEN_REQUESTS = 0.1f; @@ -405,7 +418,6 @@ void LLAvatarNameCache::idle() { // ...fall back to legacy name cache system requestNamesViaLegacy(); - llwarns << "JAMESDEBUG legacy lookup call" << llendl; } // Move requests from Ask queue to Pending queue @@ -451,11 +463,15 @@ void LLAvatarNameCache::eraseExpired() bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) { - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) + if (sRunning) { - *av_name = it->second; - return true; + // ...only do immediate lookups when cache is running + std::map::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + *av_name = it->second; + return true; + } } if (!isRequestPending(agent_id)) @@ -468,14 +484,18 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) { - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) + if (sRunning) { - // ...name already exists in cache, fire callback now - callback_signal_t signal; - signal.connect(slot); - signal(agent_id, it->second); - return; + // ...only do immediate lookups when cache is running + std::map::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + // ...name already exists in cache, fire callback now + callback_signal_t signal; + signal.connect(slot); + signal(agent_id, it->second); + return; + } } // schedule a request diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 68a6c28b7b..26cecc5ab5 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -42,7 +42,10 @@ class LLUUID; namespace LLAvatarNameCache { - void initClass(); + // 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 cleanupClass(); void importFile(std::istream& istr); @@ -52,6 +55,10 @@ namespace LLAvatarNameCache // 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? + bool hasNameLookupURL(); // Periodically makes a batch request for display names not already in // cache. Call once per frame. @@ -71,9 +78,7 @@ namespace LLAvatarNameCache // If name information is in cache, callback will be called immediately. void get(const LLUUID& agent_id, callback_slot_t slot); - // JAMESDEBUG TODO: collapse this with setNameLookupUrl? - // Not all grids support display names. If display names are disabled, - // fall back to old name lookup system. + // Allow display names to be explicitly disabled for testing. void setUseDisplayNames(bool use); bool useDisplayNames(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3b236676f1..5df6776fa7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3916,6 +3916,7 @@ void LLAppViewer::idleNameCache() // granted to neighbor regions before the main agent gets there. Can't // do it in the move-into-region code because cap not guaranteed to be // granted yet, for example on teleport. + bool had_capability = LLAvatarNameCache::hasNameLookupURL(); std::string name_lookup_url; name_lookup_url.reserve(128); // avoid a memory allocation below name_lookup_url = region->getCapability("GetDisplayNames"); @@ -3941,19 +3942,11 @@ void LLAppViewer::idleNameCache() } // Error recovery - did we change state? - if (LLAvatarNameCache::useDisplayNames() && !have_capability) + if (had_capability != have_capability) { - // ...we just lost the capability, turn names off - LLAvatarNameCache::setUseDisplayNames(false); // name tags are persistant on screen, so make sure they refresh LLVOAvatar::invalidateNameTags(); } - else if (!LLAvatarNameCache::useDisplayNames() && have_capability) - { - // ...we just gained the capability, turn names on - LLAvatarNameCache::setUseDisplayNames(true); - LLVOAvatar::invalidateNameTags(); - } LLAvatarNameCache::idle(); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7531853008..2baaf0f58f 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2771,7 +2771,9 @@ void LLStartUp::initNameCache() // Load stored cache if possible LLAppViewer::instance()->loadNameCache(); - LLAvatarNameCache::initClass(); + // Start cache in not-running state until we figure out if we have + // capabilities for display name lookup + LLAvatarNameCache::initClass(false); } void LLStartUp::cleanupNameCache() diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index adf71878f5..9fe16b5253 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7597,6 +7597,8 @@ void toggle_display_names() { bool use = LLAvatarNameCache::useDisplayNames(); LLAvatarNameCache::setUseDisplayNames(!use); + + LLVOAvatar::invalidateNameTags(); } void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) -- cgit v1.3