llmarketplacefunctions.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /**
  2. * @file llmarketplacefunctions.h
  3. * @brief Miscellaneous marketplace-related functions and classes
  4. * class definition
  5. *
  6. * $LicenseInfo:firstyear=2012&license=viewergpl$
  7. *
  8. * Copyright (c) 2012, 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 LL_LLMARKETPLACEFUNCTIONS_H
  34. #define LL_LLMARKETPLACEFUNCTIONS_H
  35. #include "boost/function.hpp"
  36. #include "boost/signals2.hpp"
  37. #include "llcorehttpheaders.h"
  38. #include "llcorehttpoptions.h"
  39. #include "llinventory.h"
  40. #include "llsingleton.h"
  41. class LLFolderBridge;
  42. class LLInventoryObserver;
  43. class LLMarketplaceData;
  44. class LLViewerInventoryCategory;
  45. class LLViewerInventoryItem;
  46. namespace MarketplaceStatusCodes
  47. {
  48. enum sCode
  49. {
  50. MARKET_PLACE_NOT_INITIALIZED = 0,
  51. MARKET_PLACE_INITIALIZING = 1,
  52. MARKET_PLACE_CONNECTION_FAILURE = 2,
  53. MARKET_PLACE_MERCHANT = 3,
  54. MARKET_PLACE_NOT_MERCHANT = 4,
  55. MARKET_PLACE_NOT_MIGRATED_MERCHANT = 5,
  56. MARKET_PLACE_MIGRATED_MERCHANT = 6
  57. };
  58. }
  59. namespace MarketplaceFetchCodes
  60. {
  61. enum sCode
  62. {
  63. MARKET_FETCH_NOT_DONE = 0,
  64. MARKET_FETCH_LOADING = 1,
  65. MARKET_FETCH_FAILED = 2,
  66. MARKET_FETCH_DONE = 3
  67. };
  68. }
  69. // Classes handling the data coming from and going to the Marketplace SLM
  70. // server DB:
  71. // * implements the Marketplace API
  72. // * caches the current Marketplace data (tuples)
  73. // * provides methods to get Marketplace data on any inventory item
  74. // * sets Marketplace data
  75. // * signals Marketplace updates to inventory
  76. namespace SLMErrorCodes
  77. {
  78. enum eCode
  79. {
  80. SLM_SUCCESS = 200,
  81. SLM_RECORD_CREATED = 201,
  82. SLM_MALFORMED_PAYLOAD = 400,
  83. SLM_NOT_FOUND = 404,
  84. };
  85. }
  86. // A Marketplace item is known by its tuple
  87. class LLMarketplaceTuple
  88. {
  89. friend class LLMarketplaceData;
  90. public:
  91. LLMarketplaceTuple();
  92. LLMarketplaceTuple(const LLUUID& folder_id);
  93. LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id,
  94. const LLUUID& version_id, bool is_listed = false);
  95. LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id,
  96. const LLUUID& version_id, bool is_listed,
  97. const std::string& edit_url, S32 count);
  98. private:
  99. // Representation of a marketplace item in the Marketplace DB (well, what
  100. // we know of it...)
  101. LLUUID mListingFolderId;
  102. LLUUID mVersionFolderId;
  103. S32 mListingId;
  104. S32 mCountOnHand;
  105. std::string mEditURL;
  106. bool mIsActive;
  107. };
  108. // Session cache of all Marketplace tuples
  109. // Notes:
  110. // * There's one and only one possible set of Marketplace dataset per agent and
  111. // per session thus making it an LLSingleton
  112. // * Some of those records might correspond to folders that do not exist in the
  113. // inventory anymore. We do not clear them out though. They just won't show
  114. // up in the UI.
  115. class LLMarketplaceData : public LLSingleton<LLMarketplaceData>
  116. {
  117. friend class LLSingleton<LLMarketplaceData>;
  118. protected:
  119. LOG_CLASS(LLMarketplaceData);
  120. public:
  121. // Public SLM API: Initialization and status
  122. typedef boost::signals2::signal<void()> status_updated_signal_t;
  123. void initializeSLM(const status_updated_signal_t::slot_type& cb);
  124. LL_INLINE U32 getSLMStatus() const { return mMarketPlaceStatus; }
  125. void setSLMStatus(S32 status);
  126. LL_INLINE void setSLMDataFetched(S32 status) { mMarketPlaceDataFetched = status; }
  127. LL_INLINE S32 getSLMDataFetched() { return mMarketPlaceDataFetched; }
  128. LL_INLINE bool isSLMDataFetched()
  129. {
  130. return mMarketPlaceDataFetched ==
  131. MarketplaceFetchCodes::MARKET_FETCH_DONE;
  132. }
  133. void getSLMListings();
  134. LL_INLINE bool isEmpty() { return mMarketplaceItems.size() == 0; }
  135. // High level create/delete/set Marketplace data: each method returns true
  136. // if the function succeeds, false if error
  137. bool createListing(const LLUUID& folder_id);
  138. bool activateListing(const LLUUID& folder_id, bool activate,
  139. S32 depth = -1);
  140. bool clearListing(const LLUUID& folder_id, S32 depth = -1);
  141. bool setVersionFolder(const LLUUID& folder_id, const LLUUID& version_id,
  142. S32 depth = -1);
  143. bool associateListing(const LLUUID& folder_id,
  144. const LLUUID& source_folder_id, S32 listing_id);
  145. bool updateCountOnHand(const LLUUID& folder_id, S32 depth = -1);
  146. bool getListing(const LLUUID& folder_id, S32 depth = -1);
  147. bool getListing(S32 listing_id);
  148. bool deleteListing(S32 listing_id, bool update = true);
  149. // Probe the Marketplace data set to identify folders
  150. // returns true if folder_id is a Listing folder
  151. bool isListed(const LLUUID& folder_id);
  152. // returns true if folder_id is an active (listed) Listing folder
  153. bool isListedAndActive(const LLUUID& folder_id);
  154. // returns true if folder_id is a Version folder
  155. bool isVersionFolder(const LLUUID& folder_id);
  156. // returns true if the obj_id is buried in an active version folder
  157. bool isInActiveFolder(const LLUUID& obj_id, S32 depth = -1);
  158. // returns the UUID of the active version folder obj_id is in
  159. LLUUID getActiveFolder(const LLUUID& obj_id, S32 depth = -1);
  160. // returns true if we're waiting from SLM incoming data for folder_id
  161. bool isUpdating(const LLUUID& folder_id, S32 depth = -1);
  162. // Access Marketplace data set: each method returns a default value if the
  163. // argument cannot be found
  164. bool getActivationState(const LLUUID& folder_id);
  165. S32 getListingID(const LLUUID& folder_id);
  166. LLUUID getVersionFolder(const LLUUID& folder_id);
  167. std::string getListingURL(const LLUUID& folder_id, S32 depth = -1);
  168. LLUUID getListingFolder(S32 listing_id);
  169. S32 getCountOnHand(const LLUUID& folder_id);
  170. // Used to flag if stock count values for Marketplace have to be updated
  171. LL_INLINE bool checkDirtyCount()
  172. {
  173. if (mDirtyCount)
  174. {
  175. mDirtyCount = false;
  176. return true;
  177. }
  178. else
  179. {
  180. return false;
  181. }
  182. }
  183. LL_INLINE void setDirtyCount() { mDirtyCount = true; }
  184. void setUpdating(const LLUUID& folder_id, bool is_updating);
  185. // Used to add to the list of folder to validate on idle callback
  186. void listForIdleValidation(const LLUUID& folder_id);
  187. // Used to decide when to run a validation on listing folders
  188. void setValidationWaiting(const LLUUID& folder_id, S32 count);
  189. void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);
  190. private:
  191. LLMarketplaceData();
  192. ~LLMarketplaceData() override;
  193. // Modify Marketplace data set: each method returns true if the function
  194. // succeeds, false if error.
  195. // Used internally only by SLM Responders when data are received from the
  196. // SLM Server
  197. bool addListing(const LLUUID& folder_id, S32 listing_id,
  198. const LLUUID& version_id, bool is_listed,
  199. const std::string& edit_url, S32 count);
  200. bool deleteListing(const LLUUID& folder_id, bool update = true);
  201. bool setListingID(const LLUUID& folder_id, S32 listing_id,
  202. bool update = true);
  203. bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id,
  204. bool update = true);
  205. bool setActivationState(const LLUUID& folder_id, bool activate,
  206. bool update = true);
  207. bool setListingURL(const LLUUID& folder_id, const std::string& edit_url,
  208. bool update = true);
  209. bool setCountOnHand(const LLUUID& folder_id, S32 count,
  210. bool update = true);
  211. // Private SLM API: package data and get/post/put requests to the SLM
  212. // server through the SLM API
  213. void createSLMListing(const LLUUID& folder_id, const LLUUID& version_id,
  214. S32 count);
  215. void getSLMListing(S32 listing_id);
  216. void updateSLMListing(const LLUUID& folder_id, S32 listing_id,
  217. const LLUUID& version_id, bool is_listed, S32 count);
  218. void associateSLMListing(const LLUUID& folder_id, S32 listing_id,
  219. const LLUUID& version_id,
  220. const LLUUID& source_folder_id);
  221. void deleteSLMListing(S32 listing_id);
  222. std::string getSLMConnectURL(const std::string& route);
  223. // Coroutines for the above methods
  224. void getMerchantStatusCoro(const std::string& url);
  225. void getSLMListingsCoro(const std::string& url, LLUUID folder_id);
  226. void getSLMListingCoro(const std::string& url, LLUUID folder_id);
  227. void createSLMListingCoro(const std::string& url, LLUUID folder_id,
  228. const LLSD& data);
  229. void updateSLMListingCoro(const std::string& url, LLUUID folder_id,
  230. LLUUID version_id, bool is_listed,
  231. const LLSD& data);
  232. void associateSLMListingCoro(const std::string& url, LLUUID folder_id,
  233. LLUUID source_folder_id, const LLSD& data);
  234. void deleteSLMListingCoro(const std::string& url, LLUUID folder_id);
  235. static void idleCallback(void* userdata);
  236. private:
  237. LLCore::HttpOptions::ptr_t mHttpOptions;
  238. LLCore::HttpHeaders::ptr_t mHttpHeaders;
  239. // Handling Marketplace connection and inventory connection
  240. S32 mMarketPlaceStatus;
  241. LLInventoryObserver* mInventoryObserver;
  242. status_updated_signal_t* mStatusUpdatedSignal;
  243. boost::signals2::connection mStatusUpdatedSlot;
  244. // If true, stock count value need to be updated at the next check
  245. bool mDirtyCount;
  246. // Update data
  247. S32 mMarketPlaceDataFetched;
  248. uuid_list_t mPendingUpdateSet;
  249. // Listing folders waiting for validation
  250. typedef fast_hmap<LLUUID, S32> waiting_list_t;
  251. waiting_list_t mValidationWaitingList;
  252. uuid_list_t mPendingValidations;
  253. // The cache of SLM data.
  254. // Notes:
  255. // * The mListingFolderId is used as a key to this map. It could therefore
  256. // be taken off the LLMarketplaceTuple objects themselves.
  257. // * The SLM DB however uses mListingId as its primary key and it shows in
  258. // its API. In the viewer though, the mListingFolderId is what we use to
  259. // grab an inventory record.
  260. typedef fast_hmap<LLUUID, LLMarketplaceTuple> marketplace_items_list_t;
  261. marketplace_items_list_t mMarketplaceItems;
  262. // We need a list (version folder -> listing folder) because such reverse
  263. // lookups are frequent
  264. typedef fast_hmap<LLUUID, LLUUID> version_folders_list_t;
  265. version_folders_list_t mVersionFolders;
  266. };
  267. // computeStockCount() return error code
  268. constexpr S32 COMPUTE_STOCK_INFINITE = -1;
  269. constexpr S32 COMPUTE_STOCK_NOT_EVALUATED = -2;
  270. // Purely static class used as an interface to the Marketplace Listings API
  271. class LLMarketplace
  272. {
  273. LLMarketplace() = delete;
  274. ~LLMarketplace() = delete;
  275. protected:
  276. LOG_CLASS(LLMarketplace);
  277. public:
  278. static void setup(bool warn = false);
  279. static void checkMerchantStatus();
  280. static bool connected();
  281. LL_INLINE static const LLUUID& getMPL() { return sMarketplaceListingId; }
  282. static bool contains(const LLUUID& item_id);
  283. static S32 depthNesting(const LLUUID& item_id);
  284. static LLUUID nestedParentId(const LLUUID& item_id, S32 depth);
  285. static S32 computeStockCount(const LLUUID& cat_id,
  286. bool force_count = false);
  287. static void updateFolderHierarchy(const LLUUID& cat_id);
  288. static void updateCategory(const LLUUID& cur_uuid,
  289. bool perform_consistency_enforcement = true);
  290. static void updateAllCounts(const LLUUID& cat_id);
  291. static void updateAllCounts(); // Called by the inventory floater
  292. typedef boost::function<void(std::string& validation_message,
  293. S32 depth,
  294. LLError::ELevel log_level)> validation_callback_t;
  295. static bool validateListings(LLViewerInventoryCategory* cat,
  296. validation_callback_t cb = NULL,
  297. bool fix_hierarchy = true, S32 depth = -1);
  298. static bool processUpdateNotification(const LLSD& data);
  299. // Inventory model action
  300. static bool updateIfListed(const LLUUID& folder_id,
  301. const LLUUID& parent_id);
  302. // Inventory bridge information
  303. static void inventoryContextMenu(LLFolderBridge* folder,
  304. const LLUUID& id, U32 flags,
  305. std::vector<std::string>& items,
  306. std::vector<std::string>& disabled_items);
  307. static std::string rootFolderLabelSuffix();
  308. static std::string folderLabelSuffix(const LLUUID& cat_id);
  309. static bool isFolderActive(const LLUUID& cat_id);
  310. static bool hasPermissionsForSale(LLViewerInventoryCategory* cat,
  311. std::string& error_msg);
  312. static bool canMoveItemInto(const LLViewerInventoryCategory* root_folder,
  313. LLViewerInventoryCategory* dest_folder,
  314. LLViewerInventoryItem* inv_item,
  315. std::string& tooltip_msg,
  316. S32 bundle_size = 1,
  317. bool from_paste = false);
  318. static bool canMoveFolderInto(const LLViewerInventoryCategory* root_folder,
  319. LLViewerInventoryCategory* dest_folder,
  320. LLViewerInventoryCategory* inv_cat,
  321. std::string& tooltip_msg,
  322. S32 bundle_size = 1,
  323. bool from_paste = false);
  324. // Inventory bridge actions
  325. static bool moveItemInto(LLViewerInventoryItem* inv_item,
  326. const LLUUID& dest_folder, bool copy = false);
  327. static bool moveFolderInto(LLViewerInventoryCategory* inv_cat,
  328. const LLUUID& dest_folder, bool copy = false,
  329. bool move_no_copy_items = false);
  330. static void updateMovedFrom(const LLUUID& from_folder_uuid,
  331. const LLUUID& cat_id = LLUUID::null);
  332. static void getListing(const LLUUID& folder_id);
  333. static void createListing(const LLUUID& folder_id);
  334. static void clearListing(const LLUUID& folder_id);
  335. static void editListing(const LLUUID& folder_id);
  336. static void listFolder(const LLUUID& folder_id, bool list = true);
  337. static void activateFolder(const LLUUID& folder_id, bool activate = true);
  338. private:
  339. static void initializeCallback();
  340. static void gatherMessage(std::string& message, S32 depth,
  341. LLError::ELevel log_level);
  342. private:
  343. static LLUUID sMarketplaceListingId;
  344. static std::string sMessage;
  345. };
  346. #endif // LL_LLMARKETPLACEFUNCTIONS_H