PageRenderTime 94ms CodeModel.GetById 40ms app.highlight 38ms RepoModel.GetById 12ms app.codeStats 0ms

/indra/newview/llwearablelist.cpp

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