llavatarnamecache.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /**
  2. * @file llavatarnamecache.h
  3. * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names
  4. * ("James Cook") from avatar UUIDs.
  5. *
  6. * $LicenseInfo:firstyear=2010&license=viewergpl$
  7. *
  8. * Copyright (c) 2010, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #ifndef LLAVATARNAMECACHE_H
  34. #define LLAVATARNAMECACHE_H
  35. #include "hbfastmap.h"
  36. #include "llcorehttputil.h"
  37. class LLFrameTimer;
  38. class LLAvatarName
  39. {
  40. public:
  41. LLAvatarName();
  42. bool operator<(const LLAvatarName& rhs) const;
  43. LLSD asLLSD() const;
  44. void fromLLSD(const LLSD& sd);
  45. // For normal names, returns "James Linden (james.linden)". When display
  46. // names are disabled returns just "James Linden"
  47. std::string getCompleteName() const;
  48. // For normal names, returns "Whatever Display Name [John Doe]" when
  49. // display name and legacy name are different, or just "John Doe" when they
  50. // are equal or when display names are disabled. When linefeed == true, the
  51. // space between the display name and the opening square bracket for the
  52. // legacy name is replaced with a line feed.
  53. std::string getNames(bool linefeed = false) const;
  54. // Returns "James Linden" or "bobsmith123 Resident" for backwards
  55. // compatibility with systems like voice and muting
  56. // Never omit "Resident" when full is true.
  57. std::string getLegacyName(bool full = false) const;
  58. public:
  59. // "bobsmith123" or "james.linden", US-ASCII only
  60. std::string mUsername;
  61. // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode. Contains
  62. // data whether or not user has explicitly set a display name; may
  63. // duplicate their username.
  64. std::string mDisplayName;
  65. // For "James Linden" -> "James"; for "bobsmith123" -> "bobsmith123".
  66. // Used to communicate with legacy systems like voice and muting which
  67. // rely on old-style names.
  68. std::string mLegacyFirstName;
  69. // For "James Linden" -> "Linden"; for "bobsmith123" -> "Resident".
  70. // See above for rationale
  71. std::string mLegacyLastName;
  72. // Under error conditions, we may insert "dummy" records with names like
  73. // "???" into caches as placeholders. These can be shown in UI, but are
  74. // not serialized.
  75. bool mIsDisplayNameDefault;
  76. // Under error conditions, we may insert "dummy" records with names equal
  77. // to legacy name into caches as placeholders. These can be shown in UI,
  78. // but are not serialized.
  79. bool mIsTemporaryName;
  80. // Names can change, so need to keep track of when name was last checked.
  81. // Unix time-from-epoch seconds for efficiency
  82. F64 mExpires;
  83. // You can only change your name every N hours, so record when the next
  84. // update is allowed. Unix time-from-epoch seconds
  85. F64 mNextUpdate;
  86. // true to prevent the displaying of "Resident" as a last name in legacy
  87. // names
  88. static bool sOmitResidentAsLastName;
  89. // true to force the use of legacy names for friends (only used in newview/
  90. // but kept here for consistency with the above flag).
  91. static bool sLegacyNamesForFriends;
  92. // true to force the use of legacy names for speakers in IM and voice
  93. // panels (only used in newview/ but kept here for consistency with the
  94. // above flag).
  95. static bool sLegacyNamesForSpeakers;
  96. };
  97. // Purely static class
  98. class LLAvatarNameCache
  99. {
  100. LLAvatarNameCache() = delete;
  101. ~LLAvatarNameCache() = delete;
  102. protected:
  103. LOG_CLASS(LLAvatarNameCache);
  104. public:
  105. typedef boost::signals2::signal<void(void)> use_display_name_signal_t;
  106. static void initClass();
  107. static void cleanupClass();
  108. static bool importFile(std::istream& istr);
  109. static void exportFile(std::ostream& ostr);
  110. // On the viewer, usually a simulator capabilitity. If empty, name cache
  111. // will fall back to using legacy name lookup system
  112. static void setNameLookupURL(const std::string& name_lookup_url);
  113. // Do we have a valid lookup URL, hence are we trying to use the new
  114. // display name lookup system ?
  115. static bool hasNameLookupURL();
  116. // Maximum number of simultaneous HTTP requests
  117. static void setMaximumRequests(U32 num);
  118. // Periodically makes a batch request for display names not already in
  119. // cache. Called once per frame.
  120. static void idle();
  121. // If name is in cache, returns true and fills in provided LLAvatarName
  122. // otherwise returns false
  123. static bool get(const LLUUID& agent_id, LLAvatarName* av_name);
  124. // Callback types for get() below
  125. typedef boost::signals2::signal<void(const LLUUID& agent_id,
  126. const LLAvatarName& av_name)>
  127. callback_signal_t;
  128. typedef callback_signal_t::slot_type callback_slot_t;
  129. typedef boost::signals2::connection callback_connection_t;
  130. // Fetches name information and calls callback. If name information is in
  131. // cache, callback will be called immediately.
  132. static callback_connection_t get(const LLUUID& agent_id,
  133. callback_slot_t slot);
  134. // Set and get the display names usage policy.
  135. static void setUseDisplayNames(U32 use);
  136. static U32 useDisplayNames();
  137. static void erase(const LLUUID& agent_id);
  138. // Provide some fallback for agents that return errors
  139. static void handleAgentError(const LLUUID& agent_id);
  140. static void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
  141. // Compute name expiration time from HTTP Cache-Control header, or return
  142. // default value, in seconds from epoch.
  143. static F64 nameExpirationFromHeaders(const LLSD& headers);
  144. static void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
  145. private:
  146. // Handle name response off network. Optionally skip adding to cache, used
  147. // when this is a fallback to the legacy name system.
  148. static void processName(const LLUUID& agent_id,
  149. const LLAvatarName& av_name, bool add_to_cache);
  150. static void requestNamesViaCapability();
  151. // Legacy name system callback
  152. static void legacyNameCallback(const LLUUID& agent_id,
  153. const std::string& full_name,
  154. bool is_group);
  155. static void requestNamesViaLegacy();
  156. // Fill in an LLAvatarName with the legacy name data
  157. static void buildLegacyName(const std::string& full_name,
  158. LLAvatarName* av_name);
  159. // Do a single callback to a given slot
  160. static void fireSignal(const LLUUID& agent_id, const callback_slot_t& slot,
  161. const LLAvatarName& av_name);
  162. // Is a request in-flight over the network ?
  163. static bool isRequestPending(const LLUUID& agent_id);
  164. // Erase expired names from cache
  165. static void eraseUnrefreshed();
  166. static bool expirationFromCacheControl(const LLSD& headers, F64* expires);
  167. static void requestAvatarNameCacheCoro(const std::string& url,
  168. uuid_vec_t agent_ids);
  169. static void handleAvNameCacheSuccess(const LLSD& data, F64 expires);
  170. private:
  171. // Usage policy for display names: 0 = legacy names, 1 = display name and
  172. // legacy name, 2 = display name (legacy if absent)
  173. static U32 sUseDisplayNames;
  174. // Time when unrefreshed cached names were checked last
  175. static F64 sLastExpireCheck;
  176. // Let's not launch too many simultaneous coroutines when filling up large
  177. // lists (group member lists, for example):
  178. static S32 sPendingRequests;
  179. static S32 sMaximumRequests;
  180. // Base lookup URL for name service capability. Includes the trailing
  181. // slash, like "http://pdp60.lindenlab.com:8000/agents/"
  182. static std::string sNameLookupURL;
  183. static use_display_name_signal_t sUseDisplayNamesSignal;
  184. // Accumulated agent IDs for next query against service
  185. static uuid_list_t sAskQueue;
  186. // Agent IDs that have been requested, but with no reply maps agent ID to
  187. // frame time request was made.
  188. typedef fast_hmap<LLUUID, F64> pending_queue_t;
  189. static pending_queue_t sPendingQueue;
  190. // Callbacks to fire when we received a name. May have multiple callbacks
  191. // for a single ID, which are represented as multiple slots bound to the
  192. // signal. Avoid copying signals via pointers.
  193. typedef fast_hmap<LLUUID, callback_signal_t*> signal_map_t;
  194. static signal_map_t sSignalMap;
  195. // Names we know about
  196. typedef fast_hmap<LLUUID, LLAvatarName> cache_t;
  197. static cache_t sCache;
  198. // Send bulk lookup requests a few times a second at most only need per-
  199. // frame timing resolution
  200. static LLFrameTimer sRequestTimer;
  201. static LLCore::HttpRequest::ptr_t sHttpRequest;
  202. static LLCore::HttpHeaders::ptr_t sHttpHeaders;
  203. static LLCore::HttpOptions::ptr_t sHttpOptions;
  204. // Cache starts in a paused state until we can determine if the current
  205. // region supports display names.
  206. static bool sRunning;
  207. };
  208. #endif