/indra/newview/llwearablelist.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 263 lines · 193 code · 32 blank · 38 comment · 21 complexity · 2252a26a1b57ce02753ef672f6d2a5d1 MD5 · raw file

  1. /**
  2. * @file llwearablelist.cpp
  3. * @brief LLWearableList class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llwearablelist.h"
  28. #include "message.h"
  29. #include "llassetstorage.h"
  30. #include "llagent.h"
  31. #include "llvoavatar.h"
  32. #include "llviewerstats.h"
  33. #include "llnotificationsutil.h"
  34. #include "llinventorymodel.h"
  35. #include "lltrans.h"
  36. // Callback struct
  37. struct LLWearableArrivedData
  38. {
  39. LLWearableArrivedData(LLAssetType::EType asset_type,
  40. const std::string& wearable_name,
  41. void(*asset_arrived_callback)(LLWearable*, void* userdata),
  42. void* userdata) :
  43. mAssetType( asset_type ),
  44. mCallback( asset_arrived_callback ),
  45. mUserdata( userdata ),
  46. mName( wearable_name ),
  47. mRetries(0)
  48. {}
  49. LLAssetType::EType mAssetType;
  50. void (*mCallback)(LLWearable*, void* userdata);
  51. void* mUserdata;
  52. std::string mName;
  53. S32 mRetries;
  54. };
  55. ////////////////////////////////////////////////////////////////////////////
  56. // LLWearableList
  57. LLWearableList::~LLWearableList()
  58. {
  59. cleanup();
  60. }
  61. void LLWearableList::cleanup()
  62. {
  63. for_each(mList.begin(), mList.end(), DeletePairedPointer());
  64. mList.clear();
  65. }
  66. void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
  67. {
  68. llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
  69. LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
  70. if( instance )
  71. {
  72. asset_arrived_callback( instance, userdata );
  73. }
  74. else
  75. {
  76. gAssetStorage->getAssetData(assetID,
  77. asset_type,
  78. LLWearableList::processGetAssetReply,
  79. (void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
  80. TRUE);
  81. }
  82. }
  83. // static
  84. void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID& uuid, void* userdata, S32 status, LLExtStat ext_status )
  85. {
  86. BOOL isNewWearable = FALSE;
  87. LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
  88. LLWearable* wearable = NULL; // NULL indicates failure
  89. if( !filename )
  90. {
  91. LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
  92. }
  93. else if (status >= 0)
  94. {
  95. // read the file
  96. LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/
  97. if( !fp )
  98. {
  99. LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
  100. }
  101. else
  102. {
  103. wearable = new LLWearable(uuid);
  104. bool res = wearable->importFile( fp );
  105. if (!res)
  106. {
  107. if (wearable->getType() == LLWearableType::WT_COUNT)
  108. {
  109. isNewWearable = TRUE;
  110. }
  111. delete wearable;
  112. wearable = NULL;
  113. }
  114. fclose( fp );
  115. if(filename)
  116. {
  117. LLFile::remove(std::string(filename));
  118. }
  119. }
  120. }
  121. else
  122. {
  123. if(filename)
  124. {
  125. LLFile::remove(std::string(filename));
  126. }
  127. LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
  128. LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;
  129. switch( status )
  130. {
  131. case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
  132. {
  133. // Fail
  134. break;
  135. }
  136. default:
  137. {
  138. static const S32 MAX_RETRIES = 3;
  139. if (data->mRetries < MAX_RETRIES)
  140. {
  141. // Try again
  142. data->mRetries++;
  143. gAssetStorage->getAssetData(uuid,
  144. data->mAssetType,
  145. LLWearableList::processGetAssetReply,
  146. userdata); // re-use instead of deleting.
  147. return;
  148. }
  149. else
  150. {
  151. // Fail
  152. break;
  153. }
  154. }
  155. }
  156. }
  157. if (wearable) // success
  158. {
  159. LLWearableList::instance().mList[ uuid ] = wearable;
  160. LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
  161. LL_DEBUGS("Wearable") << wearable << LL_ENDL;
  162. }
  163. else
  164. {
  165. LLSD args;
  166. args["TYPE"] =LLTrans::getString(LLAssetType::lookupHumanReadable(data->mAssetType));
  167. if (isNewWearable)
  168. {
  169. LLNotificationsUtil::add("InvalidWearable");
  170. }
  171. else if (data->mName.empty())
  172. {
  173. LLNotificationsUtil::add("FailedToFindWearableUnnamed", args);
  174. }
  175. else
  176. {
  177. args["DESC"] = data->mName;
  178. LLNotificationsUtil::add("FailedToFindWearable", args);
  179. }
  180. }
  181. // Always call callback; wearable will be NULL if we failed
  182. {
  183. if( data->mCallback )
  184. {
  185. data->mCallback( wearable, data->mUserdata );
  186. }
  187. }
  188. delete data;
  189. }
  190. LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
  191. {
  192. lldebugs << "LLWearableList::createCopy()" << llendl;
  193. LLWearable *wearable = generateNewWearable();
  194. wearable->copyDataFrom(old_wearable);
  195. LLPermissions perm(old_wearable->getPermissions());
  196. perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
  197. wearable->setPermissions(perm);
  198. if (!new_name.empty()) wearable->setName(new_name);
  199. // Send to the dataserver
  200. wearable->saveNewAsset();
  201. return wearable;
  202. }
  203. LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
  204. {
  205. lldebugs << "LLWearableList::createNewWearable()" << llendl;
  206. LLWearable *wearable = generateNewWearable();
  207. wearable->setType( type );
  208. std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );
  209. wearable->setName( name );
  210. LLPermissions perm;
  211. perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
  212. perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
  213. wearable->setPermissions(perm);
  214. // Description and sale info have default values.
  215. wearable->setParamsToDefaults();
  216. wearable->setTexturesToDefaults();
  217. //mark all values (params & images) as saved
  218. wearable->saveValues();
  219. // Send to the dataserver
  220. wearable->saveNewAsset();
  221. return wearable;
  222. }
  223. LLWearable *LLWearableList::generateNewWearable()
  224. {
  225. LLTransactionID tid;
  226. tid.generate();
  227. LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  228. LLWearable* wearable = new LLWearable(tid);
  229. mList[new_asset_id] = wearable;
  230. return wearable;
  231. }