llinventorymodel.h 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. /**
  2. * @file llinventorymodel.h
  3. * @brief LLInventoryModel class header file
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLINVENTORYMODEL_H
  33. #define LL_LLINVENTORYMODEL_H
  34. #include <map>
  35. #include <set>
  36. #include <string>
  37. #include <vector>
  38. #include "boost/optional.hpp"
  39. #include "llassettype.h"
  40. #include "llcorehttpheaders.h"
  41. #include "llcorehttpoptions.h"
  42. #include "llcorehttprequest.h"
  43. #include "hbfastmap.h"
  44. #include "llfoldertype.h"
  45. #include "llpermissionsflags.h"
  46. #include "llstring.h"
  47. #include "lluuid.h"
  48. #include "llviewerinventory.h"
  49. class LLInventoryCategory;
  50. class LLInventoryCollectFunctor;
  51. class LLInventoryItem;
  52. class LLInventoryObject;
  53. class LLMessageSystem;
  54. class LLViewerInventoryItem;
  55. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  56. // Class LLInventoryObserver
  57. //
  58. // This class is designed to be a simple abstract base class which can
  59. // relay messages when the inventory changes.
  60. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61. class LLInventoryObserver
  62. {
  63. public:
  64. // This enumeration is a way to refer to what changed in a more human
  65. // readable format. You can mask the value provided by changed() to see if
  66. // the observer is interested in the change.
  67. enum
  68. {
  69. NONE = 0,
  70. LABEL = 1, // Name changed
  71. INTERNAL = 2, // Internal change, eg, asset UUID different
  72. ADD = 4, // Something added
  73. REMOVE = 8, // Something deleted
  74. STRUCTURE = 16, // Structural change, eg, item or folder moved
  75. CALLING_CARD = 32, // Online, grant status, cancel, etc change
  76. REBUILD = 128, // Icon changed, for example. Rebuild all.
  77. CREATE = 512, // With ADD, item has just been created.
  78. ALL = 0xffffffff
  79. };
  80. virtual ~LLInventoryObserver() = default;
  81. virtual void changed(U32 mask) = 0;
  82. };
  83. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84. // LLInventoryModel
  85. //
  86. // Represents a collection of inventory, and provides efficient ways to access
  87. // that information.
  88. // NOTE: This class could in theory be used for any place where you need
  89. // inventory, though it optimizes for time efficiency - not space efficiency,
  90. // probably making it inappropriate for use on tasks.
  91. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  92. class LLInventoryModel
  93. {
  94. protected:
  95. LOG_CLASS(LLInventoryModel);
  96. public:
  97. LLInventoryModel();
  98. ~LLInventoryModel();
  99. void cleanupInventory();
  100. typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
  101. typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
  102. protected:
  103. // Empty the entire contents
  104. void empty();
  105. //--------------------------------------------------------------------
  106. // Initialization
  107. //--------------------------------------------------------------------
  108. private:
  109. // One-time initialization of HTTP system.
  110. void initHttpRequest();
  111. public:
  112. // The inventory model usage is sensitive to the initial construction of
  113. // the model
  114. bool isInventoryUsable() const;
  115. //--------------------------------------------------------------------
  116. // Root Folders
  117. //--------------------------------------------------------------------
  118. // The following are set during login with data from the server
  119. void setRootFolderID(const LLUUID& id);
  120. void setLibraryOwnerID(const LLUUID& id);
  121. void setLibraryRootFolderID(const LLUUID& id);
  122. LL_INLINE const LLUUID& getRootFolderID() const { return mRootFolderID; }
  123. LL_INLINE const LLUUID& getLibraryOwnerID() const
  124. {
  125. return mLibraryOwnerID;
  126. }
  127. LL_INLINE const LLUUID& getLibraryRootFolderID() const
  128. {
  129. return mLibraryRootFolderID;
  130. }
  131. // Commonly used folders. HB
  132. const LLUUID& getTrashID();
  133. const LLUUID& getLostAndFoundID();
  134. //--------------------------------------------------------------------
  135. // Structure
  136. //--------------------------------------------------------------------
  137. // Methods to load up inventory skeleton & meat. These are used during
  138. // authentication. Returns true if everything parsed.
  139. bool loadSkeleton(const LLSD& options, const LLUUID& owner_id);
  140. // Brute force method to rebuild the entire parent-child relations.
  141. void buildParentChildMap();
  142. std::string getCacheFileName(const LLUUID& agent_id);
  143. // Call on logout to save a terse representation.
  144. void cache(const LLUUID& parent_folder_id, const LLUUID& agent_id);
  145. // Consolidates and (re)-creates any missing system folder. May be used as
  146. // a menu callback.
  147. static void checkSystemFolders(void* dummy_data_ptr = NULL);
  148. //--------------------------------------------------------------------
  149. // Descendents
  150. //--------------------------------------------------------------------
  151. // Make sure we have the descendents in the structure.
  152. void fetchDescendentsOf(const LLUUID& folder_id);
  153. // Returns the direct descendents of the id provided. Sets passed in values
  154. // to NULL if the call fails.
  155. // NOTE: the array provided points straight into the guts of this object,
  156. // and should only be used for read operations, since modifications may
  157. // invalidate the internal state of the inventory.
  158. void getDirectDescendentsOf(const LLUUID& cat_id, cat_array_t*& categories,
  159. item_array_t*& items) const;
  160. enum
  161. {
  162. EXCLUDE_TRASH = false,
  163. INCLUDE_TRASH = true
  164. };
  165. // Starting with the object specified, add its descendents to the array
  166. // provided, but do not add the inventory object specified by id. There is
  167. // no guaranteed order.
  168. // NOTE: Neither array will be erased before adding objects to it. Do not
  169. // store a copy of the pointers collected - use them, and collect them
  170. // again later if you need to reference the same objects.
  171. void collectDescendents(const LLUUID& id, cat_array_t& categories,
  172. item_array_t& items, bool include_trash);
  173. void collectDescendentsIf(const LLUUID& id, cat_array_t& categories,
  174. item_array_t& items, bool include_trash,
  175. LLInventoryCollectFunctor& add);
  176. // Collect all items in inventory that are linked to item_id. Assumes
  177. // item_id is itself not a linked item.
  178. item_array_t collectLinkedItems(const LLUUID& item_id,
  179. const LLUUID& start_folder = LLUUID::null);
  180. // Checks if one object has a parent chain up to the category specified by
  181. // UUID.
  182. bool isObjectDescendentOf(const LLUUID& obj_id,
  183. const LLUUID& cat_id) const;
  184. // Returns true when inv_object_id is in trash; forces the creation of the
  185. // Trash folder when absent. HB
  186. LL_INLINE bool isInTrash(const LLUUID& inv_object_id)
  187. {
  188. return isObjectDescendentOf(inv_object_id, getTrashID());
  189. }
  190. // Returns true when inv_object_id is in the current outfit folder; does
  191. // *not* force the creation of the COF when absent. HB
  192. bool isInCOF(const LLUUID& inv_object_id) const;
  193. // Returns true when inv_object_id is in market place folder; does
  194. // *not* force the creation of the Marketplace Listings folder when
  195. // absent. HB
  196. bool isInMarketPlace(const LLUUID& inv_object_id) const;
  197. //--------------------------------------------------------------------
  198. // Find
  199. //--------------------------------------------------------------------
  200. // Returns the UUID of the category that specifies 'type' as what it
  201. // defaults to containing. The category is not necessarily only for that
  202. // type. NOTE: If create_folder is true, this will create a new inventory
  203. // category on the fly if one does not exist.
  204. LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type,
  205. bool create_folder = true);
  206. // Returns the UUID of the category that specifies 'type' as what its
  207. // choosen (user defined) folder. If the user-defined folder does not
  208. // exist, it is equivalent to calling findCategoryUUIDForType(type, true)
  209. LLUUID findChoosenCategoryUUIDForType(LLFolderType::EType preferred_type);
  210. // Get first descendant of the child object under the specified parent
  211. const LLViewerInventoryCategory* getFirstDescendantOf(const LLUUID& parent_id,
  212. const LLUUID& obj_id) const;
  213. // Get the object by id. Returns NULL if not found.
  214. // NOTE: Use the pointer returned for read operations - do not modify the
  215. // object values in place or you will break stuff.
  216. LLInventoryObject* getObject(const LLUUID& id) const;
  217. // Get the item by id. Returns NULL if not found.
  218. // NOTE: Use the pointer for read operations - use the updateItem() method
  219. // to actually modify values.
  220. LLViewerInventoryItem* getItem(const LLUUID& id) const;
  221. // Get the category by id. Returns NULL if not found.
  222. // NOTE: Use the pointer for read operations - use the updateCategory()
  223. // method to actually modify values.
  224. LLViewerInventoryCategory* getCategory(const LLUUID& id) const;
  225. // Get the inventoryID that this item points to, else just return item_id
  226. const LLUUID& getLinkedItemID(const LLUUID& object_id) const;
  227. // Copies the contents of all folders of type "type" into folder "id" and
  228. // delete/purge the empty folders. When is_root_cat is true, also makes
  229. // sure that id is parented to the root folder. Note: the trash is also
  230. // emptied in the process.
  231. void consolidateForType(const LLUUID& id, LLFolderType::EType type,
  232. bool is_root_cat = true);
  233. protected:
  234. // Internal method which looks for a category with the specified
  235. // preferred type. Returns LLUUID::null if not found
  236. LLUUID findCatUUID(LLFolderType::EType preferred_type);
  237. //--------------------------------------------------------------------
  238. // Count
  239. //--------------------------------------------------------------------
  240. public:
  241. // Return the number of items or categories
  242. S32 getItemCount() const;
  243. S32 getCategoryCount() const;
  244. //
  245. // Mutators
  246. //
  247. // Change an existing item with a matching item_id or add the item to the
  248. // current inventory. Returns the change mask generated by the update. No
  249. // notification will be sent to observers. This method will only generate
  250. // network traffic if the item had to be reparented.
  251. // NOTE: In usage, you will want to perform cache accounting operations in
  252. // LLInventoryModel::accountForUpdate() or
  253. // LLViewerInventoryItem::updateServer() before calling this method.
  254. U32 updateItem(const LLViewerInventoryItem* item, U32 mask = 0);
  255. // Change an existing item with the matching id or add the category. No
  256. // notification will be sent to observers. This method will only generate
  257. // network traffic if the item had to be reparented.
  258. // NOTE: In usage, you will want to perform cache accounting operations in
  259. // accountForUpdate() or LLViewerInventoryCategory::updateServer() before
  260. // calling this method.
  261. void updateCategory(const LLViewerInventoryCategory* catp, U32 mask = 0);
  262. // Move the specified object id to the specified category and update the
  263. // internal structures. No cache accounting, observer notification, or
  264. // server update is performed.
  265. void moveObject(const LLUUID& object_id, const LLUUID& cat_id);
  266. // Migrated from llinventorybridge.cpp
  267. void changeItemParent(LLViewerInventoryItem* itemp,
  268. const LLUUID& new_parent_id, bool restamp);
  269. // Migrated from llinventorybridge.cpp
  270. void changeCategoryParent(LLViewerInventoryCategory* catp,
  271. const LLUUID& new_parent_id, bool restamp);
  272. void checkTrashOverflow();
  273. //--------------------------------------------------------------------
  274. // Delete
  275. //--------------------------------------------------------------------
  276. // Update model after an item is confirmed as removed from server. Works
  277. // for categories or items.
  278. void onObjectDeletedFromServer(const LLUUID& item_id,
  279. bool fix_broken_links = true,
  280. bool update_parent_version = true,
  281. bool do_notify_observers = true);
  282. // Update model after all descendents removed from server.
  283. void onDescendentsPurgedFromServer(const LLUUID& object_id,
  284. bool fix_broken_links = true);
  285. #if 0 // Do not appear to be used currently.
  286. // Update model after an existing item gets updated on server.
  287. void onItemUpdated(const LLUUID& item_id, const LLSD& updates,
  288. bool update_parent_version);
  289. // Update model after an existing category gets updated on server.
  290. void onCategoryUpdated(const LLUUID& cat_id, const LLSD& updates);
  291. #endif
  292. // Delete a particular inventory object by ID. Will purge one object from
  293. // the internal data structures, maintaining a consistent internal state.
  294. // No cache accounting or server update is performed.
  295. void deleteObject(const LLUUID& id, bool fix_broken_links = true,
  296. bool do_notify_observers = true);
  297. // Moves item item_id to Trash
  298. void removeItem(const LLUUID& item_id);
  299. // Moves category category_id to Trash
  300. void removeCategory(const LLUUID& category_id);
  301. //--------------------------------------------------------------------
  302. // Creation
  303. //--------------------------------------------------------------------
  304. // Creates a new category. If you want to use the default name based on
  305. // type, pass an empty string as the 'name' parameter.
  306. // AIS3 will be used to create the category if available and enabled, else
  307. // the "CreateInventoryCategory" capability will be used if present (it
  308. // should exist even in OpenSim) and finally a fall back to the legacy
  309. // createCategoryUDP() method below is performed when there is no such
  310. // capability available; in all cases the category Id is transmitted
  311. // (asynchronously for when AIS3 or the capability were used) via the
  312. // callback function, provided it is not NULL (you may pass NULL, if you
  313. // do not need the category UUID to perform other operations with it).
  314. void createNewCategory(const LLUUID& parent_id,
  315. LLFolderType::EType preferred_type,
  316. const std::string& name,
  317. inventory_func_t callback,
  318. const LLUUID& thumbnail_id = LLUUID::null);
  319. // Same as above, but this method uses the legacy "CreateInventoryFolder"
  320. // UDP message (see note) and the UUID of the created category is then
  321. // immediately returned instead of using a callback function.
  322. // In case of error (unusable inventory or unknown 'preferred_type'), this
  323. // method returns a null UUID.
  324. // Note: the "CreateInventoryFolder" UDP message might stop working at some
  325. // point in the future in SL; as of 2023-10 the latest SL release
  326. // viewer already got rid of its usage in its code. HB
  327. LLUUID createCategoryUDP(const LLUUID& parent_id,
  328. LLFolderType::EType preferred_type,
  329. const std::string& name,
  330. const LLUUID& thumbnail_id = LLUUID::null);
  331. void rebuildBrokenLinks();
  332. protected:
  333. void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
  334. // Internal methods that add inventory and make sure that all of the
  335. // internal data structures are consistent. These methods should be passed
  336. // pointers of newly created objects, and the instance will take over the
  337. // memory management from there.
  338. void addCategory(LLViewerInventoryCategory* category);
  339. void addItem(LLViewerInventoryItem* item);
  340. void createNewCategoryCoro(const std::string& url, const LLSD& data,
  341. LLUUID thumb_id, inventory_func_t callback);
  342. //
  343. // Category accounting.
  344. //
  345. public:
  346. // Represents the number of items added or removed from a category.
  347. struct LLCategoryUpdate
  348. {
  349. LL_INLINE LLCategoryUpdate()
  350. : mDescendentDelta(0),
  351. mChangeVersion(true)
  352. {
  353. }
  354. LL_INLINE LLCategoryUpdate(const LLUUID& category_id, S32 delta,
  355. bool change_version = true)
  356. : mCategoryID(category_id),
  357. mDescendentDelta(delta),
  358. mChangeVersion(change_version)
  359. {
  360. }
  361. LLUUID mCategoryID;
  362. S32 mDescendentDelta;
  363. bool mChangeVersion;
  364. };
  365. typedef std::vector<LLCategoryUpdate> update_list_t;
  366. // This exists to make it easier to account for deltas in a map.
  367. struct LLInitializedS32
  368. {
  369. LL_INLINE LLInitializedS32()
  370. : mValue(0)
  371. {
  372. }
  373. LL_INLINE LLInitializedS32(S32 value)
  374. : mValue(value)
  375. {
  376. }
  377. LL_INLINE LLInitializedS32& operator++() { ++mValue; return *this; }
  378. LL_INLINE LLInitializedS32& operator--() { --mValue; return *this; }
  379. S32 mValue;
  380. };
  381. typedef fast_hmap<LLUUID, LLInitializedS32> update_map_t;
  382. // Call these methods when there are category updates, but call them
  383. // *before* the actual update so the method can do descendent accounting
  384. // correctly.
  385. void accountForUpdate(const LLCategoryUpdate& update) const;
  386. void accountForUpdate(const update_list_t& updates) const;
  387. void accountForUpdate(const update_map_t& updates) const;
  388. enum EHasChildren
  389. {
  390. CHILDREN_NO,
  391. CHILDREN_YES,
  392. CHILDREN_MAYBE
  393. };
  394. // Returns (yes/no/maybe) child status of category children.
  395. EHasChildren categoryHasChildren(const LLUUID& cat_id) const;
  396. // Returns true if category version is known and theoretical
  397. // descendents == actual descendents.
  398. bool isCategoryComplete(const LLUUID& cat_id) const;
  399. //
  400. // Notifications
  401. //
  402. // Called by the idle loop. Only updates if new state is detected. Call
  403. // notifyObservers() manually to update regardless of whether state change
  404. // has been indicated.
  405. void idleNotifyObservers();
  406. // Call to explicitly update everyone on a new state.
  407. void notifyObservers();
  408. // Allows outsiders to tell the inventory if something has been changed
  409. // 'under the hood', but outside the control of the inventory. The next
  410. // notify will include that notification.
  411. void addChangedMask(U32 mask, const LLUUID& referent);
  412. LL_INLINE const uuid_list_t& getChangedIDs() { return mChangedItemIDs; }
  413. LL_INLINE const uuid_list_t& getAddedIDs() { return mAddedItemIDs; }
  414. protected:
  415. // Updates all linked items pointing to this id.
  416. void addChangedMaskForLinks(const LLUUID& object_id, U32 mask);
  417. //--------------------------------------------------------------------
  418. // Observers
  419. //--------------------------------------------------------------------
  420. public:
  421. // If the observer is destroyed, be sure to remove it.
  422. void addObserver(LLInventoryObserver* observerp);
  423. void removeObserver(LLInventoryObserver* observerp);
  424. bool containsObserver(LLInventoryObserver* observerp);
  425. //--------------------------------------------------------------------
  426. // HTTP Transport
  427. //--------------------------------------------------------------------
  428. // HTTP handler for individual item requests (inventory or library).
  429. // Background item requests are derived from this in the background
  430. // inventory system. All folder requests are also located there but have
  431. // their own handler derived from HttpHandler.
  432. class FetchItemHttpHandler : public LLCore::HttpHandler
  433. {
  434. protected:
  435. LOG_CLASS(FetchItemHttpHandler);
  436. public:
  437. FetchItemHttpHandler(const LLSD& request_sd);
  438. FetchItemHttpHandler(const FetchItemHttpHandler&) = delete;
  439. void operator=(const FetchItemHttpHandler&) = delete;
  440. void onCompleted(LLCore::HttpHandle handle,
  441. LLCore::HttpResponse* response) override;
  442. private:
  443. void processData(LLSD& body, LLCore::HttpResponse* response);
  444. void processFailure(LLCore::HttpStatus status,
  445. LLCore::HttpResponse* response);
  446. void processFailure(const char* const reason,
  447. LLCore::HttpResponse* response);
  448. protected:
  449. LLSD mRequestSD;
  450. };
  451. // Invoke handler completion method (onCompleted) for all requests that are
  452. // ready.
  453. void handleResponses(bool foreground);
  454. // Request an inventory HTTP operation to either the foreground or
  455. // background processor. These are actually the same service queue but the
  456. // background requests are seviced more slowly effectively de-prioritizing
  457. // new requests.
  458. LLCore::HttpHandle requestPost(bool foreground, const std::string& url,
  459. const LLSD& body,
  460. const LLCore::HttpHandler::ptr_t& handler,
  461. // This must be a static const char* !
  462. const char* message);
  463. //--------------------------------------------------------------------
  464. // Callbacks
  465. //--------------------------------------------------------------------
  466. // Message handling functionality
  467. static void registerCallbacks(LLMessageSystem* msg);
  468. //--------------------------------------------------------------------
  469. // File I/O
  470. //--------------------------------------------------------------------
  471. protected:
  472. static bool loadFromFile(const std::string& filename,
  473. cat_array_t& categories, item_array_t& items,
  474. uuid_list_t& cats_to_update,
  475. bool& is_cache_obsolete);
  476. static bool saveToFile(const std::string& filename,
  477. const cat_array_t& categories,
  478. const item_array_t& items);
  479. //--------------------------------------------------------------------
  480. // Message handling functionality
  481. //--------------------------------------------------------------------
  482. public:
  483. static void processUpdateCreateInventoryItem(LLMessageSystem* msg, void**);
  484. static void removeInventoryItem(LLUUID agent_id, LLMessageSystem* msg,
  485. const char* msg_label);
  486. static void processRemoveInventoryItem(LLMessageSystem* msg, void**);
  487. static void processUpdateInventoryFolder(LLMessageSystem* msg, void**);
  488. static void removeInventoryFolder(LLUUID agent_id, LLMessageSystem* msg);
  489. static void processRemoveInventoryFolder(LLMessageSystem* msg, void**);
  490. static void processRemoveInventoryObjects(LLMessageSystem* msg, void**);
  491. static void processSaveAssetIntoInventory(LLMessageSystem* msg, void**);
  492. static void processBulkUpdateInventory(LLMessageSystem* msg, void**);
  493. static void processInventoryDescendents(LLMessageSystem* msg, void**);
  494. static void processMoveInventoryItem(LLMessageSystem* msg, void**);
  495. static void processFetchInventoryReply(LLMessageSystem* msg, void**);
  496. protected:
  497. bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting,
  498. U32 mask = 0);
  499. cat_array_t* getUnlockedCatArray(const LLUUID& id);
  500. item_array_t* getUnlockedItemArray(const LLUUID& id);
  501. public:
  502. //--------------------------------------------------------------------
  503. // Other
  504. //--------------------------------------------------------------------
  505. // Generates a string containing the path to the item specified by
  506. // item_id.
  507. void appendPath(const LLUUID& id, std::string& path);
  508. //--------------------------------------------------------------------
  509. // Debugging
  510. //--------------------------------------------------------------------
  511. void dumpInventory();
  512. #if LL_HAS_ASSERT
  513. void lockDirectDescendentArrays(const LLUUID& cat_id, cat_array_t*& cats,
  514. item_array_t*& items);
  515. void unlockDirectDescendentArrays(const LLUUID& cat_id);
  516. private:
  517. fast_hmap<LLUUID, bool> mCategoryLock;
  518. fast_hmap<LLUUID, bool> mItemLock;
  519. #endif
  520. //--------------------------------------------------------------------
  521. // Member variables
  522. //--------------------------------------------------------------------
  523. private:
  524. LLUUID mRootFolderID;
  525. LLUUID mLibraryRootFolderID;
  526. LLUUID mLibraryOwnerID;
  527. // Often used and *irremovable* folder Ids, cached for speed. HB
  528. LLUUID mTrashID;
  529. LLUUID mLostAndFoundID;
  530. // Cache for recent lookups
  531. mutable LLPointer<LLViewerInventoryItem> mLastItem;
  532. // Observers
  533. typedef std::set<LLInventoryObserver*> observer_list_t;
  534. observer_list_t mObservers;
  535. // Usual plumbing for LLCore:: HTTP operations.
  536. LLCore::HttpRequest* mHttpRequestFG;
  537. LLCore::HttpRequest* mHttpRequestBG;
  538. LLCore::HttpOptions::ptr_t mHttpOptions;
  539. LLCore::HttpHeaders::ptr_t mHttpHeaders;
  540. LLCore::HttpRequest::policy_t mHttpPolicyClass;
  541. // Information for tracking the actual inventory. We index this information
  542. // in a lot of different ways so we can access the inventory using several
  543. // different identifiers. mCategoryMap and mItemMap store uuid->object
  544. // mappings.
  545. typedef fast_hmap<LLUUID, LLPointer<LLViewerInventoryCategory> > cat_map_t;
  546. cat_map_t mCategoryMap;
  547. typedef fast_hmap<LLUUID, LLPointer<LLViewerInventoryItem> > item_map_t;
  548. item_map_t mItemMap;
  549. // This last set of indices is used to map parents to children.
  550. typedef fast_hmap<LLUUID, cat_array_t*> parent_cat_map_t;
  551. parent_cat_map_t mParentChildCategoryTree;
  552. typedef fast_hmap<LLUUID, item_array_t*> parent_item_map_t;
  553. parent_item_map_t mParentChildItemTree;
  554. // Map of the inventory item UUIDs which got broken link inventory items;
  555. // the said link items UUIDs are stored in a vector.
  556. typedef fast_hmap<LLUUID, uuid_vec_t> broken_links_map_t;
  557. broken_links_map_t mBrokenLinks;
  558. // List of links to rebuild after we received the linked item data.
  559. uuid_vec_t mLinksRebuildList;
  560. // Variables used to track what has changed since the last notify.
  561. uuid_list_t mChangedItemIDs;
  562. uuid_list_t mChangedItemIDsBacklog;
  563. uuid_list_t mAddedItemIDs;
  564. uuid_list_t mAddedItemIDsBacklog;
  565. U32 mModifyMask;
  566. U32 mModifyMaskBacklog;
  567. // Used to handle an invalid inventory state
  568. bool mIsAgentInvUsable;
  569. // Flag set at notifyObservers() entance and reset at its end, to detect
  570. // both, bogus recursive calls (should never happen, in theory), and calls
  571. // to addChangedMask() within an inventory observer called from
  572. // notifyObservers() (see below), which might happen, sometimes, after
  573. // an operation that triggered an asynchronous inventory fetch.
  574. bool mIsNotifyObservers;
  575. public:
  576. // Wear all clothing in this transaction
  577. static LLUUID sWearNewClothingTransactionID;
  578. // *HACK: until we can route this info through the instant message
  579. // hierarchy
  580. static bool sWearNewClothing;
  581. };
  582. // a special inventory model for the agent
  583. extern LLInventoryModel gInventory;
  584. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  585. // Class LLInventoryCollectFunctor
  586. //
  587. // Base class for LLInventoryModel::collectDescendentsIf() method which accepts
  588. // an instance of one of these objects to use as the function to determine if
  589. // it should be added. Derive from this class and override the () operator to
  590. // return true if you want to collect the category or item passed in.
  591. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  592. class LLInventoryCollectFunctor
  593. {
  594. public:
  595. virtual ~LLInventoryCollectFunctor() = default;
  596. virtual bool operator()(LLInventoryCategory* cat,
  597. LLInventoryItem* item) = 0;
  598. static bool itemTransferCommonlyAllowed(LLInventoryItem* item);
  599. };
  600. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  601. // Class LLAssetIDMatches
  602. //
  603. // This functor finds inventory items pointing to the specified asset
  604. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  605. class LLAssetIDMatches : public LLInventoryCollectFunctor
  606. {
  607. public:
  608. LL_INLINE LLAssetIDMatches(const LLUUID& asset_id)
  609. : mAssetID(asset_id)
  610. {
  611. }
  612. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  613. protected:
  614. LLUUID mAssetID;
  615. };
  616. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  617. // Class LLLinkedItemIDMatches
  618. //
  619. // This functor finds inventory items linked to the specific inventory id.
  620. // Assumes the inventory id is itself not a linked item.
  621. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  622. class LLLinkedItemIDMatches : public LLInventoryCollectFunctor
  623. {
  624. public:
  625. LL_INLINE LLLinkedItemIDMatches(const LLUUID& item_id)
  626. : mBaseItemID(item_id)
  627. {
  628. }
  629. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  630. protected:
  631. LLUUID mBaseItemID;
  632. };
  633. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  634. // Class LLIsType
  635. //
  636. // Implementation of a LLInventoryCollectFunctor which returns true if the type
  637. // is the type passed in during construction.
  638. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  639. class LLIsType : public LLInventoryCollectFunctor
  640. {
  641. public:
  642. LL_INLINE LLIsType(LLAssetType::EType type)
  643. : mType(type)
  644. {
  645. }
  646. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  647. protected:
  648. LLAssetType::EType mType;
  649. };
  650. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  651. // Class LLIsNotType
  652. //
  653. // Implementation of a LLInventoryCollectFunctor which returns false if the
  654. // type is the type passed in during construction, otherwise false.
  655. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  656. class LLIsNotType : public LLInventoryCollectFunctor
  657. {
  658. public:
  659. LL_INLINE LLIsNotType(LLAssetType::EType type)
  660. : mType(type)
  661. {
  662. }
  663. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  664. protected:
  665. LLAssetType::EType mType;
  666. };
  667. class LLIsTypeWithPermissions : public LLInventoryCollectFunctor
  668. {
  669. public:
  670. LL_INLINE LLIsTypeWithPermissions(LLAssetType::EType type,
  671. const PermissionBit perms,
  672. const LLUUID& agent_id,
  673. const LLUUID& group_id)
  674. : mType(type),
  675. mPerm(perms),
  676. mAgentID(agent_id),
  677. mGroupID(group_id)
  678. {
  679. }
  680. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  681. protected:
  682. LLAssetType::EType mType;
  683. PermissionBit mPerm;
  684. LLUUID mAgentID;
  685. LLUUID mGroupID;
  686. };
  687. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  688. // Class LLBuddyCollector
  689. //
  690. // Simple class that collects calling cards that are not null, and not the
  691. // agent; the card may have been given or recreated. Duplicates are possible.
  692. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  693. class LLBuddyCollector final : public LLInventoryCollectFunctor
  694. {
  695. public:
  696. LLBuddyCollector() = default;
  697. bool operator()(LLInventoryCategory*, LLInventoryItem* item) override;
  698. };
  699. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  700. // Class LLUniqueBuddyCollector
  701. //
  702. // Simple class that collects calling cards that are not null, and not the
  703. // agent; the card may have been given or recreated. Duplicates are discarded.
  704. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  705. class LLUniqueBuddyCollector final : public LLInventoryCollectFunctor
  706. {
  707. public:
  708. LLUniqueBuddyCollector() = default;
  709. bool operator()(LLInventoryCategory*, LLInventoryItem* item) override;
  710. private:
  711. uuid_list_t mFoundIds;
  712. };
  713. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  714. // Class LLParticularBuddyCollector
  715. //
  716. // Simple class that collects calling cards that match a particular UUID
  717. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  718. class LLParticularBuddyCollector final : public LLInventoryCollectFunctor
  719. {
  720. public:
  721. LL_INLINE LLParticularBuddyCollector(const LLUUID& id)
  722. : mBuddyID(id)
  723. {
  724. }
  725. bool operator()(LLInventoryCategory*, LLInventoryItem* item) override;
  726. protected:
  727. LLUUID mBuddyID;
  728. };
  729. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  730. // Class LLNameCategoryCollector
  731. //
  732. // Collects categories based on case-insensitive match of prefix
  733. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  734. class LLNameCategoryCollector final : public LLInventoryCollectFunctor
  735. {
  736. public:
  737. LL_INLINE LLNameCategoryCollector(const std::string& name)
  738. : mName(name)
  739. {
  740. }
  741. bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override;
  742. protected:
  743. std::string mName;
  744. };
  745. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  746. // Class LLEnvSettingsCollector
  747. //
  748. // Collects environment settings items.
  749. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  750. class LLEnvSettingsCollector final : public LLInventoryCollectFunctor
  751. {
  752. public:
  753. LLEnvSettingsCollector() = default;
  754. LL_INLINE bool operator()(LLInventoryCategory*,
  755. LLInventoryItem* item) override
  756. {
  757. return item && item->getType() == LLAssetType::AT_SETTINGS;
  758. }
  759. };
  760. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  761. // Class LLInventoryCompletionObserver
  762. //
  763. // Class which can be used as a base class for doing something when all the
  764. // observed items are locally complete. This class implements the changed()
  765. // method of LLInventoryObserver and declares a new method named done() which
  766. // is called when all watched items have complete information in the inventory
  767. // model.
  768. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  769. class LLInventoryCompletionObserver : public LLInventoryObserver
  770. {
  771. public:
  772. LLInventoryCompletionObserver() = default;
  773. void changed(U32 mask) override;
  774. void watchItem(const LLUUID& id);
  775. protected:
  776. virtual void done() = 0;
  777. protected:
  778. uuid_vec_t mComplete;
  779. uuid_vec_t mIncomplete;
  780. };
  781. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  782. // Class LLInventoryFetchObserver
  783. //
  784. // This class is much like the LLInventoryCompletionObserver, except that it
  785. // handles all the the fetching necessary. Override the done() method to do the
  786. // thing you want.
  787. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  788. class LLInventoryFetchObserver : public LLInventoryObserver
  789. {
  790. public:
  791. LLInventoryFetchObserver() = default;
  792. void changed(U32 mask) override;
  793. bool isFinished() const;
  794. virtual void fetchItems(const uuid_vec_t& ids);
  795. virtual void done() = 0;
  796. protected:
  797. uuid_vec_t mComplete;
  798. uuid_vec_t mIncomplete;
  799. };
  800. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  801. // Class LLInventoryFetchDescendentsObserver
  802. //
  803. // This class is much like the LLInventoryCompletionObserver, except that it
  804. // handles fetching based on category. Override the done() method to do the
  805. // thing you want.
  806. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  807. class LLInventoryFetchDescendentsObserver : public LLInventoryObserver
  808. {
  809. public:
  810. LLInventoryFetchDescendentsObserver() = default;
  811. void changed(U32 mask) override;
  812. void fetchDescendents(const uuid_vec_t& ids);
  813. bool isFinished() const;
  814. virtual void done() = 0;
  815. protected:
  816. bool isCategoryComplete(LLViewerInventoryCategory* cat);
  817. uuid_vec_t mIncompleteFolders;
  818. uuid_vec_t mCompleteFolders;
  819. };
  820. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  821. // Class LLInventoryFetchComboObserver
  822. //
  823. // This class does an appropriate combination of fetch descendents and item
  824. // fetches based on completion of categories and items. Much like the fetch and
  825. // fetch descendents, this will call done() when everything has arrived.
  826. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  827. class LLInventoryFetchComboObserver : public LLInventoryObserver
  828. {
  829. public:
  830. LL_INLINE LLInventoryFetchComboObserver()
  831. : mDone(false)
  832. {
  833. }
  834. void changed(U32 mask) override;
  835. void fetch(const uuid_vec_t& folder_ids, const uuid_vec_t& item_ids);
  836. virtual void done() = 0;
  837. protected:
  838. uuid_vec_t mCompleteFolders;
  839. uuid_vec_t mIncompleteFolders;
  840. uuid_vec_t mCompleteItems;
  841. uuid_vec_t mIncompleteItems;
  842. bool mDone;
  843. };
  844. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  845. // Class LLInventoryExistenceObserver
  846. //
  847. // This class is used as a base class for doing somethign when all the observed
  848. // item ids exist in the inventory somewhere. You can derive a class from this
  849. // class and implement the done() method to do something useful.
  850. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  851. class LLInventoryExistenceObserver : public LLInventoryObserver
  852. {
  853. public:
  854. LLInventoryExistenceObserver() = default;
  855. void changed(U32 mask) override;
  856. void watchItem(const LLUUID& id);
  857. protected:
  858. virtual void done() = 0;
  859. protected:
  860. uuid_vec_t mExist;
  861. uuid_vec_t mMIA;
  862. };
  863. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  864. // Class LLInventoryAddedObserver
  865. //
  866. // This class is used as a base class for doing something when a new item
  867. // arrives in inventory. It does not watch for a certain UUID, rather it acts
  868. // when anything is added Derive a class from this class and implement the
  869. // done() method to do something useful.
  870. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  871. class LLInventoryAddedObserver : public LLInventoryObserver
  872. {
  873. public:
  874. LLInventoryAddedObserver() = default;
  875. void changed(U32 mask) override;
  876. // Only used by copy_inventory_item() for now (if you implement new ways of
  877. // copying inventory items, you should use this too to avoid a false "added
  878. // item" positive). HB
  879. static void registerCopiedItem(const LLUUID& item_id);
  880. protected:
  881. virtual void done() = 0;
  882. protected:
  883. uuid_vec_t mAdded;
  884. // We keep track of the items we copy from the inventory, so to avoid a
  885. // false "added item" positive when the server creates the copy (this is
  886. // not a new item we received from a third party, so it shall not be added
  887. // to mAdded). HB
  888. typedef fast_hmap<LLUUID, U32> hashes_map_t;
  889. static hashes_map_t sCopiedItemsHashes;
  890. };
  891. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  892. // Class LLInventoryTransactionObserver
  893. //
  894. // Class which can be used as a base class for doing something when an
  895. // inventory transaction completes.
  896. //
  897. // NOTE: this class is not quite complete. Avoid using unless you fix up its
  898. // functionality gaps.
  899. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  900. class LLInventoryTransactionObserver : public LLInventoryObserver
  901. {
  902. public:
  903. LL_INLINE LLInventoryTransactionObserver(const LLTransactionID& tid)
  904. : mTransactionID(tid)
  905. {
  906. }
  907. void changed(U32 mask) override;
  908. protected:
  909. virtual void done(const uuid_vec_t& folders,
  910. const uuid_vec_t& items) = 0;
  911. protected:
  912. LLTransactionID mTransactionID;
  913. };
  914. #endif // LL_LLINVENTORYMODEL_H