llwearablelist.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llwearablelist.cpp
  3.  * @brief LLWearableList class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, 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 "message.h"
  35. #include "llassetstorage.h"
  36. #include "llagent.h"
  37. #include "llvoavatar.h"
  38. #include "llviewerstats.h"
  39. #include "llnotificationsutil.h"
  40. #include "llinventorymodel.h"
  41. #include "lltrans.h"
  42. // Callback struct
  43. struct LLWearableArrivedData
  44. {
  45. LLWearableArrivedData(LLAssetType::EType asset_type,
  46. const std::string& wearable_name,
  47. void(*asset_arrived_callback)(LLWearable*, void* userdata),
  48.   void* userdata) :
  49. mAssetType( asset_type ),
  50. mCallback( asset_arrived_callback ), 
  51. mUserdata( userdata ),
  52. mName( wearable_name ),
  53. mRetries(0)
  54. {}
  55. LLAssetType::EType mAssetType;
  56. void (*mCallback)(LLWearable*, void* userdata);
  57. void* mUserdata;
  58. std::string mName;
  59. S32 mRetries;
  60. };
  61. ////////////////////////////////////////////////////////////////////////////
  62. // LLWearableList
  63. LLWearableList::~LLWearableList()
  64. {
  65. llassert_always(mList.empty()) ;
  66. }
  67. void LLWearableList::cleanup() 
  68. {
  69. for_each(mList.begin(), mList.end(), DeletePairedPointer());
  70. mList.clear();
  71. }
  72. void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
  73. {
  74. llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
  75. LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
  76. if( instance )
  77. {
  78. asset_arrived_callback( instance, userdata );
  79. }
  80. else
  81. {
  82. gAssetStorage->getAssetData(assetID,
  83. asset_type,
  84. LLWearableList::processGetAssetReply,
  85. (void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
  86. TRUE);
  87. }
  88. }
  89. // static
  90. void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID& uuid, void* userdata, S32 status, LLExtStat ext_status )
  91. {
  92. BOOL isNewWearable = FALSE;
  93. LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
  94. LLWearable* wearable = NULL; // NULL indicates failure
  95. if( !filename )
  96. {
  97. LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
  98. }
  99. else if (status >= 0)
  100. {
  101. // read the file
  102. LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/
  103. if( !fp )
  104. {
  105. LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
  106. }
  107. else
  108. {
  109. wearable = new LLWearable(uuid);
  110. bool res = wearable->importFile( fp );
  111. if (!res)
  112. {
  113. if (wearable->getType() == WT_COUNT)
  114. {
  115. isNewWearable = TRUE;
  116. }
  117. delete wearable;
  118. wearable = NULL;
  119. }
  120. fclose( fp );
  121. if(filename)
  122. {
  123. LLFile::remove(std::string(filename));
  124. }
  125. }
  126. }
  127. else
  128. {
  129. if(filename)
  130. {
  131. LLFile::remove(std::string(filename));
  132. }
  133. LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
  134. LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;
  135. switch( status )
  136. {
  137.   case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
  138.   {
  139.   // Fail
  140.   break;
  141. }
  142.   default:
  143. {
  144.   static const S32 MAX_RETRIES = 3;
  145.   if (data->mRetries < MAX_RETRIES)
  146.   {
  147.   // Try again
  148.   data->mRetries++;
  149.   gAssetStorage->getAssetData(uuid,
  150.   data->mAssetType,
  151.   LLWearableList::processGetAssetReply,
  152.   userdata);  // re-use instead of deleting.
  153.   return;
  154. }
  155.   else
  156.   {
  157.   // Fail
  158.   break;
  159.   }
  160.   }
  161. }
  162. }
  163. if (wearable) // success
  164. {
  165. LLWearableList::instance().mList[ uuid ] = wearable;
  166. LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
  167. LL_DEBUGS("Wearable") << wearable << LL_ENDL;
  168. }
  169. else
  170. {
  171. LLSD args;
  172. args["TYPE"] =LLTrans::getString(LLAssetType::lookupHumanReadable(data->mAssetType));
  173. if (isNewWearable)
  174. {
  175. LLNotificationsUtil::add("InvalidWearable");
  176. }
  177. else if (data->mName.empty())
  178. {
  179. LLNotificationsUtil::add("FailedToFindWearableUnnamed", args);
  180. }
  181. else
  182. {
  183. args["DESC"] = data->mName;
  184. LLNotificationsUtil::add("FailedToFindWearable", args);
  185. }
  186. }
  187. // Always call callback; wearable will be NULL if we failed
  188. {
  189. if( data->mCallback )
  190. {
  191. data->mCallback( wearable, data->mUserdata );
  192. }
  193. }
  194. delete data;
  195. }
  196. LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
  197. {
  198. lldebugs << "LLWearableList::createCopy()" << llendl;
  199. LLWearable *wearable = generateNewWearable();
  200. wearable->copyDataFrom(old_wearable);
  201. LLPermissions perm(old_wearable->getPermissions());
  202. perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
  203. wearable->setPermissions(perm);
  204. if (!new_name.empty()) wearable->setName(new_name);
  205. // Send to the dataserver
  206. wearable->saveNewAsset();
  207. return wearable;
  208. }
  209. LLWearable* LLWearableList::createNewWearable( EWearableType type )
  210. {
  211. lldebugs << "LLWearableList::createNewWearable()" << llendl;
  212. LLWearable *wearable = generateNewWearable();
  213. wearable->setType( type );
  214. std::string name = "New ";
  215. name.append( wearable->getTypeLabel() );
  216. wearable->setName( name );
  217. LLPermissions perm;
  218. perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
  219. perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
  220. wearable->setPermissions(perm);
  221. // Description and sale info have default values.
  222. wearable->setParamsToDefaults();
  223. wearable->setTexturesToDefaults();
  224. //mark all values (params & images) as saved
  225. wearable->saveValues();
  226. // Send to the dataserver
  227. wearable->saveNewAsset();
  228. return wearable;
  229. }
  230. LLWearable *LLWearableList::generateNewWearable()
  231. {
  232. LLTransactionID tid;
  233. tid.generate();
  234. LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  235. LLWearable* wearable = new LLWearable(tid);
  236. mList[new_asset_id] = wearable;
  237. return wearable;
  238. }