llwearablelist.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /**
  2. * @file llwearablelist.cpp
  3. * @brief LLWearableList class implementation
  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. #include "llviewerprecompiledheaders.h"
  33. #include "llwearablelist.h"
  34. #include "llapp.h"
  35. #include "llassetstorage.h"
  36. #include "llnotifications.h"
  37. #include "lltrans.h"
  38. #include "llmessage.h"
  39. #include "llagent.h"
  40. #include "llfloaterperms.h"
  41. #include "llviewerinventory.h"
  42. #include "llviewerstats.h"
  43. #include "llvoavatar.h"
  44. // Callback struct
  45. struct LLWearableArrivedData
  46. {
  47. LLWearableArrivedData(LLAssetType::EType asset_type,
  48. const std::string& wearable_name,
  49. LLAvatarAppearance* avatarp,
  50. void (*asset_arrived_callback)(LLViewerWearable*,
  51. void*),
  52. void* userdata)
  53. : mAssetType(asset_type),
  54. mCallback(asset_arrived_callback),
  55. mUserdata(userdata),
  56. mName(wearable_name),
  57. mRetries(0),
  58. mAvatarp(avatarp)
  59. {
  60. }
  61. LLAssetType::EType mAssetType;
  62. void (*mCallback)(LLViewerWearable*, void* userdata);
  63. void* mUserdata;
  64. std::string mName;
  65. S32 mRetries;
  66. LLAvatarAppearance* mAvatarp;
  67. };
  68. ////////////////////////////////////////////////////////////////////////////
  69. // LLWearableList
  70. LLWearableList::~LLWearableList()
  71. {
  72. cleanup();
  73. }
  74. void LLWearableList::cleanup()
  75. {
  76. for (wearable_map_t::iterator it = mList.begin(), end = mList.end();
  77. it != end; ++it)
  78. {
  79. // Ensure that the corresponding LLWearable still exists !
  80. if (LLWearable::sWearableList.count((LLWearable*)it->second))
  81. {
  82. delete it->second;
  83. }
  84. }
  85. mList.clear();
  86. }
  87. void LLWearableList::getAsset(const LLAssetID& asset_id,
  88. const std::string& wearable_name,
  89. LLAvatarAppearance* avatarp,
  90. LLAssetType::EType asset_type,
  91. void(*asset_arrived_callback)(LLViewerWearable*,
  92. void*),
  93. void* userdata)
  94. {
  95. llassert(asset_type == LLAssetType::AT_CLOTHING ||
  96. asset_type == LLAssetType::AT_BODYPART);
  97. LLViewerWearable* instance = get_ptr_in_map(mList, asset_id);
  98. if (instance &&
  99. // Ensure that the corresponding LLWearable still exists !
  100. LLWearable::sWearableList.count((LLWearable*)instance))
  101. {
  102. asset_arrived_callback(instance, userdata);
  103. }
  104. else
  105. {
  106. gAssetStoragep->getAssetData(asset_id, asset_type,
  107. LLWearableList::processGetAssetReply,
  108. (void*)new LLWearableArrivedData(asset_type,
  109. wearable_name,
  110. avatarp,
  111. asset_arrived_callback,
  112. userdata),
  113. true);
  114. }
  115. }
  116. // static
  117. void LLWearableList::processGetAssetReply(const char* filename,
  118. const LLAssetID& uuid,
  119. void* userdata,
  120. S32 status,
  121. LLExtStat ext_status)
  122. {
  123. LLWearableArrivedData* data = (LLWearableArrivedData*)userdata;
  124. if (LLApp::isExiting())
  125. {
  126. // Abort in case we got disconnected before the reply came back (seen
  127. // happening due to network disconnections). HB
  128. delete data;
  129. return;
  130. }
  131. bool is_new_wearable = false;
  132. LLViewerWearable* wearable = NULL; // NULL indicates failure
  133. LLAvatarAppearance* avatarp = data->mAvatarp;
  134. if (!filename)
  135. {
  136. llwarns << "Bad Wearable Asset: missing file." << llendl;
  137. }
  138. else if (!avatarp)
  139. {
  140. llwarns << "Bad asset request: missing avatar pointer." << llendl;
  141. }
  142. else if (status >= 0)
  143. {
  144. // read the file
  145. llifstream ifs(filename, std::ifstream::binary);
  146. if (!ifs.is_open())
  147. {
  148. llwarns << "Bad Wearable Asset: unable to open file: '" << filename
  149. << "'" << llendl;
  150. }
  151. else
  152. {
  153. wearable = new LLViewerWearable(uuid);
  154. if (wearable->importStream(ifs, avatarp) != LLWearable::SUCCESS)
  155. {
  156. if (wearable->getType() == LLWearableType::WT_COUNT)
  157. {
  158. is_new_wearable = true;
  159. }
  160. delete wearable;
  161. wearable = NULL;
  162. }
  163. if (ifs.is_open())
  164. {
  165. ifs.close();
  166. }
  167. LLFile::remove(filename);
  168. }
  169. }
  170. else
  171. {
  172. if (filename)
  173. {
  174. LLFile::remove(filename);
  175. }
  176. gViewerStats.incStat(LLViewerStats::ST_DOWNLOAD_FAILED);
  177. llwarns << "Wearable download failed: "
  178. << LLAssetStorage::getErrorString(status) << " " << uuid
  179. << llendl;
  180. switch (status)
  181. {
  182. case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
  183. break; // failed
  184. default:
  185. {
  186. constexpr S32 MAX_RETRIES = 3;
  187. if (data->mRetries < MAX_RETRIES)
  188. {
  189. // Try again
  190. ++data->mRetries;
  191. gAssetStoragep->getAssetData(uuid, data->mAssetType,
  192. processGetAssetReply,
  193. // re-use instead of deleting:
  194. userdata);
  195. return;
  196. }
  197. // failed
  198. }
  199. }
  200. }
  201. if (wearable) // success
  202. {
  203. LLWearableList::getInstance()->mList[uuid] = wearable;
  204. LL_DEBUGS("Wearables") << "Success getting wearable: " << uuid.asString()
  205. << LL_ENDL;
  206. }
  207. else
  208. {
  209. LLSD args;
  210. args["TYPE"] = LLTrans::getString(LLAssetType::lookupHumanReadable(data->mAssetType));
  211. if (is_new_wearable)
  212. {
  213. gNotifications.add("InvalidWearable");
  214. }
  215. else if (data->mName.empty())
  216. {
  217. gNotifications.add("FailedToFindWearableUnnamed", args);
  218. }
  219. else
  220. {
  221. args["DESC"] = data->mName;
  222. gNotifications.add("FailedToFindWearable", args);
  223. }
  224. }
  225. // Always call callback; wearable will be NULL if we failed
  226. if (data->mCallback)
  227. {
  228. data->mCallback(wearable, data->mUserdata);
  229. }
  230. delete data;
  231. }
  232. LLViewerWearable* LLWearableList::createCopy(LLViewerWearable* old_wearable,
  233. const std::string& new_name)
  234. {
  235. LLViewerWearable* wearable = generateNewWearable();
  236. wearable->copyDataFrom(old_wearable);
  237. LLPermissions perm(old_wearable->getPermissions());
  238. perm.setOwnerAndGroup(LLUUID::null, gAgentID, LLUUID::null, true);
  239. wearable->setPermissions(perm);
  240. if (!new_name.empty())
  241. {
  242. wearable->setName(new_name);
  243. }
  244. // Send to the dataserver
  245. wearable->saveNewAsset();
  246. return wearable;
  247. }
  248. LLViewerWearable* LLWearableList::createNewWearable(LLWearableType::EType type,
  249. LLAvatarAppearance* avatarp)
  250. {
  251. LLViewerWearable* wearable = generateNewWearable();
  252. wearable->setType(type, avatarp);
  253. std::string name =
  254. LLTrans::getString(LLWearableType::getTypeDefaultNewName(wearable->getType()));
  255. wearable->setName(name);
  256. LLPermissions perm;
  257. perm.init(gAgentID, gAgentID, LLUUID::null, LLUUID::null);
  258. perm.initMasks(PERM_ALL, PERM_ALL,
  259. LLFloaterPerms::getEveryonePerms(),
  260. LLFloaterPerms::getGroupPerms(),
  261. LLFloaterPerms::getNextOwnerPerms() | PERM_MOVE);
  262. wearable->setPermissions(perm);
  263. wearable->setDefinitionVersion(LLWearable::getCurrentDefinitionVersion());
  264. // Description and sale info have default values.
  265. wearable->setParamsToDefaults();
  266. wearable->setTexturesToDefaults();
  267. // Mark all values (params & images) as saved
  268. wearable->saveValues();
  269. // Send to the dataserver
  270. wearable->saveNewAsset();
  271. return wearable;
  272. }
  273. LLViewerWearable* LLWearableList::generateNewWearable()
  274. {
  275. LLTransactionID tid;
  276. tid.generate();
  277. LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  278. LLViewerWearable* wearable = new LLViewerWearable(tid);
  279. mList[new_asset_id] = wearable;
  280. return wearable;
  281. }