PageRenderTime 127ms CodeModel.GetById 15ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llagentwearables.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2081 lines | 1614 code | 245 blank | 222 comment | 273 complexity | 4fe5f617409047e528a25ad5b73075c3 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/** 
   2 * @file llagentwearables.cpp
   3 * @brief LLAgentWearables class implementation
   4 *
   5 * $LicenseInfo:firstyear=2001&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#include "llagentwearables.h"
  29
  30#include "llaccordionctrltab.h"
  31#include "llagent.h"
  32#include "llagentcamera.h"
  33#include "llagentwearablesfetch.h"
  34#include "llappearancemgr.h"
  35#include "llcallbacklist.h"
  36#include "llfloatersidepanelcontainer.h"
  37#include "llgesturemgr.h"
  38#include "llinventorybridge.h"
  39#include "llinventoryfunctions.h"
  40#include "llinventoryobserver.h"
  41#include "llinventorypanel.h"
  42#include "llmd5.h"
  43#include "llnotificationsutil.h"
  44#include "lloutfitobserver.h"
  45#include "llsidepanelappearance.h"
  46#include "lltexlayer.h"
  47#include "lltooldraganddrop.h"
  48#include "llviewerregion.h"
  49#include "llvoavatarself.h"
  50#include "llwearable.h"
  51#include "llwearablelist.h"
  52
  53#include <boost/scoped_ptr.hpp>
  54
  55LLAgentWearables gAgentWearables;
  56
  57BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
  58
  59using namespace LLVOAvatarDefines;
  60
  61///////////////////////////////////////////////////////////////////////////////
  62
  63// Callback to wear and start editing an item that has just been created.
  64class LLWearAndEditCallback : public LLInventoryCallback
  65{
  66	void fire(const LLUUID& inv_item)
  67	{
  68		if (inv_item.isNull()) return;
  69
  70		// Request editing the item after it gets worn.
  71		gAgentWearables.requestEditingWearable(inv_item);
  72
  73		// Wear it.
  74		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
  75	}
  76};
  77
  78///////////////////////////////////////////////////////////////////////////////
  79
  80// HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"
  81// Some db items are corrupted, have inventory flags = 0, implying wearable type = shape, even though
  82// wearable type stored in asset is some other value.
  83// Calling this function whenever a wearable is added to increase visibility if this problem
  84// turns up in other inventories.
  85void checkWearableAgainstInventory(LLWearable *wearable)
  86{
  87	if (wearable->getItemID().isNull())
  88		return;
  89	
  90	// Check for wearable type consistent with inventory item wearable type.
  91	LLViewerInventoryItem *item = gInventory.getItem(wearable->getItemID());
  92	if (item)
  93	{
  94		if (!item->isWearableType())
  95		{
  96			llwarns << "wearable associated with non-wearable item" << llendl;
  97		}
  98		if (item->getWearableType() != wearable->getType())
  99		{
 100			llwarns << "type mismatch: wearable " << wearable->getName()
 101					<< " has type " << wearable->getType()
 102					<< " but inventory item " << item->getName()
 103					<< " has type "  << item->getWearableType() << llendl;
 104		}
 105	}
 106	else
 107	{
 108		llwarns << "wearable inventory item not found" << wearable->getName()
 109				<< " itemID " << wearable->getItemID().asString() << llendl;
 110	}
 111}
 112
 113void LLAgentWearables::dump()
 114{
 115	llinfos << "LLAgentWearablesDump" << llendl;
 116	for (S32 i = 0; i < LLWearableType::WT_COUNT; i++)
 117	{
 118		U32 count = getWearableCount((LLWearableType::EType)i);
 119		llinfos << "Type: " << i << " count " << count << llendl;
 120		for (U32 j=0; j<count; j++)
 121		{
 122			LLWearable* wearable = getWearable((LLWearableType::EType)i,j);
 123			if (wearable == NULL)
 124			{
 125				llinfos << "    " << j << " NULL wearable" << llendl;
 126			}
 127			llinfos << "    " << j << " Name " << wearable->getName()
 128					<< " description " << wearable->getDescription() << llendl;
 129			
 130		}
 131	}
 132	llinfos << "Total items awaiting wearable update " << mItemsAwaitingWearableUpdate.size() << llendl;
 133	for (std::set<LLUUID>::iterator it = mItemsAwaitingWearableUpdate.begin();
 134		 it != mItemsAwaitingWearableUpdate.end();
 135		 ++it)
 136	{
 137		llinfos << (*it).asString() << llendl;
 138	}
 139}
 140
 141struct LLAgentDumper
 142{
 143	LLAgentDumper(std::string name):
 144		mName(name)
 145	{
 146		llinfos << llendl;
 147		llinfos << "LLAgentDumper " << mName << llendl;
 148		gAgentWearables.dump();
 149	}
 150
 151	~LLAgentDumper()
 152	{
 153		llinfos << llendl;
 154		llinfos << "~LLAgentDumper " << mName << llendl;
 155		gAgentWearables.dump();
 156	}
 157
 158	std::string mName;
 159};
 160
 161LLAgentWearables::LLAgentWearables() :
 162	mWearablesLoaded(FALSE)
 163,	mCOFChangeInProgress(false)
 164{
 165}
 166
 167LLAgentWearables::~LLAgentWearables()
 168{
 169	cleanup();
 170}
 171
 172void LLAgentWearables::cleanup()
 173{
 174}
 175
 176// static
 177void LLAgentWearables::initClass()
 178{
 179	// this can not be called from constructor because its instance is global and is created too early.
 180	// Subscribe to "COF is Saved" signal to notify observers about this (Loading indicator for ex.).
 181	LLOutfitObserver::instance().addCOFSavedCallback(boost::bind(&LLAgentWearables::notifyLoadingFinished, &gAgentWearables));
 182}
 183
 184void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
 185{ 
 186	if (avatar)
 187	{
 188		sendAgentWearablesRequest();
 189	}
 190}
 191
 192// wearables
 193LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
 194{
 195	llinfos << "destructor - all done?" << llendl;
 196	gAgentWearables.createStandardWearablesAllDone();
 197}
 198
 199LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback()
 200{
 201	gAgentWearables.sendAgentWearablesUpdate();
 202}
 203
 204/**
 205 * @brief Construct a callback for dealing with the wearables.
 206 *
 207 * Would like to pass the agent in here, but we can't safely
 208 * count on it being around later.  Just use gAgent directly.
 209 * @param cb callback to execute on completion (??? unused ???)
 210 * @param type Type for the wearable in the agent
 211 * @param wearable The wearable data.
 212 * @param todo Bitmask of actions to take on completion.
 213 */
 214LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
 215	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
 216	mType(type),
 217	mIndex(index),	
 218	mWearable(wearable),
 219	mTodo(todo),
 220	mCB(cb)
 221{
 222	llinfos << "constructor" << llendl;
 223}
 224
 225void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
 226{
 227	if (mTodo & CALL_CREATESTANDARDDONE)
 228	{
 229		llinfos << "callback fired, inv_item " << inv_item.asString() << llendl;
 230	}
 231
 232	if (inv_item.isNull())
 233		return;
 234
 235	gAgentWearables.addWearabletoAgentInventoryDone(mType, mIndex, inv_item, mWearable);
 236
 237	if (mTodo & CALL_UPDATE)
 238	{
 239		gAgentWearables.sendAgentWearablesUpdate();
 240	}
 241	if (mTodo & CALL_RECOVERDONE)
 242	{
 243		LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
 244		gAgentWearables.recoverMissingWearableDone();
 245	}
 246	/*
 247	 * Do this for every one in the loop
 248	 */
 249	if (mTodo & CALL_CREATESTANDARDDONE)
 250	{
 251		LLAppearanceMgr::instance().addCOFItemLink(inv_item,false);
 252		gAgentWearables.createStandardWearablesDone(mType, mIndex);
 253	}
 254	if (mTodo & CALL_MAKENEWOUTFITDONE)
 255	{
 256		gAgentWearables.makeNewOutfitDone(mType, mIndex);
 257	}
 258	if (mTodo & CALL_WEARITEM)
 259	{
 260		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true);
 261	}
 262}
 263
 264void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
 265													   const U32 index,
 266													   const LLUUID& item_id,
 267													   LLWearable* wearable)
 268{
 269	llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
 270
 271	if (item_id.isNull())
 272		return;
 273
 274	LLUUID old_item_id = getWearableItemID(type,index);
 275
 276	if (wearable)
 277	{
 278		wearable->setItemID(item_id);
 279
 280		if (old_item_id.notNull())
 281		{	
 282			gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
 283			setWearable(type,index,wearable);
 284		}
 285		else
 286		{
 287			pushWearable(type,wearable);
 288		}
 289	}
 290
 291	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 292
 293	LLViewerInventoryItem* item = gInventory.getItem(item_id);
 294	if (item && wearable)
 295	{
 296		// We're changing the asset id, so we both need to set it
 297		// locally via setAssetUUID() and via setTransactionID() which
 298		// will be decoded on the server. JC
 299		item->setAssetUUID(wearable->getAssetID());
 300		item->setTransactionID(wearable->getTransactionID());
 301		gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
 302		item->updateServer(FALSE);
 303	}
 304	gInventory.notifyObservers();
 305}
 306
 307void LLAgentWearables::sendAgentWearablesUpdate()
 308{
 309	// First make sure that we have inventory items for each wearable
 310	for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
 311	{
 312		for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
 313		{
 314			LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
 315			if (wearable)
 316			{
 317				if (wearable->getItemID().isNull())
 318				{
 319					LLPointer<LLInventoryCallback> cb =
 320						new addWearableToAgentInventoryCallback(
 321							LLPointer<LLRefCount>(NULL),
 322							(LLWearableType::EType)type,
 323							index,
 324							wearable,
 325							addWearableToAgentInventoryCallback::CALL_NONE);
 326					addWearableToAgentInventory(cb, wearable);
 327				}
 328				else
 329				{
 330					gInventory.addChangedMask(LLInventoryObserver::LABEL,
 331											  wearable->getItemID());
 332				}
 333			}
 334		}
 335	}
 336
 337	// Then make sure the inventory is in sync with the avatar.
 338	gInventory.notifyObservers();
 339
 340	// Send the AgentIsNowWearing 
 341	gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
 342
 343	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
 344	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 345	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 346
 347	lldebugs << "sendAgentWearablesUpdate()" << llendl;
 348	// MULTI-WEARABLE: DEPRECATED: HACK: index to 0- server database tables don't support concept of multiwearables.
 349	for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
 350	{
 351		gMessageSystem->nextBlockFast(_PREHASH_WearableData);
 352
 353		U8 type_u8 = (U8)type;
 354		gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
 355
 356		LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
 357		if (wearable)
 358		{
 359			//llinfos << "Sending wearable " << wearable->getName() << llendl;
 360			LLUUID item_id = wearable->getItemID();
 361			const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 362			if (item && item->getIsLinkType())
 363			{
 364				// Get the itemID that this item points to.  i.e. make sure
 365				// we are storing baseitems, not their links, in the database.
 366				item_id = item->getLinkedUUID();
 367			}
 368			gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);			
 369		}
 370		else
 371		{
 372			//llinfos << "Not wearing wearable type " << LLWearableType::getTypeName((LLWearableType::EType)i) << llendl;
 373			gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null);
 374		}
 375
 376		lldebugs << "       " << LLWearableType::getTypeLabel((LLWearableType::EType)type) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl;
 377	}
 378	gAgent.sendReliableMessage();
 379}
 380
 381void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
 382									const std::string new_name)
 383{
 384	LLWearable* old_wearable = getWearable(type, index);
 385	if(!old_wearable) return;
 386	bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
 387	if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
 388	{
 389		LLUUID old_item_id = old_wearable->getItemID();
 390		LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
 391		new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
 392		setWearable(type,index,new_wearable);
 393
 394		// old_wearable may still be referred to by other inventory items. Revert
 395		// unsaved changes so other inventory items aren't affected by the changes
 396		// that were just saved.
 397		old_wearable->revertValues();
 398
 399		LLInventoryItem* item = gInventory.getItem(old_item_id);
 400		if (item)
 401		{
 402			std::string item_name = item->getName();
 403			if (name_changed)
 404			{
 405				llinfos << "saveWearable changing name from "  << item->getName() << " to " << new_name << llendl;
 406				item_name = new_name;
 407			}
 408			// Update existing inventory item
 409			LLPointer<LLViewerInventoryItem> template_item =
 410				new LLViewerInventoryItem(item->getUUID(),
 411										  item->getParentUUID(),
 412										  item->getPermissions(),
 413										  new_wearable->getAssetID(),
 414										  new_wearable->getAssetType(),
 415										  item->getInventoryType(),
 416										  item_name,
 417										  item->getDescription(),
 418										  item->getSaleInfo(),
 419										  item->getFlags(),
 420										  item->getCreationDate());
 421			template_item->setTransactionID(new_wearable->getTransactionID());
 422			template_item->updateServer(FALSE);
 423			gInventory.updateItem(template_item);
 424			if (name_changed)
 425			{
 426				gInventory.notifyObservers();
 427			}
 428		}
 429		else
 430		{
 431			// Add a new inventory item (shouldn't ever happen here)
 432			U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
 433			if (send_update)
 434			{
 435				todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
 436			}
 437			LLPointer<LLInventoryCallback> cb =
 438				new addWearableToAgentInventoryCallback(
 439					LLPointer<LLRefCount>(NULL),
 440					type,
 441					index,
 442					new_wearable,
 443					todo);
 444			addWearableToAgentInventory(cb, new_wearable);
 445			return;
 446		}
 447
 448		gAgentAvatarp->wearableUpdated( type, TRUE );
 449
 450		if (send_update)
 451		{
 452			sendAgentWearablesUpdate();
 453		}
 454	}
 455}
 456
 457void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 458									  const U32 index,
 459									  const std::string& new_name,
 460									  BOOL save_in_lost_and_found)
 461{
 462	if (!isWearableCopyable(type, index))
 463	{
 464		llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
 465		return;
 466	}
 467	LLWearable* old_wearable = getWearable(type, index);
 468	if (!old_wearable)
 469	{
 470		llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
 471		return;
 472	}
 473
 474	LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index));
 475	if (!item)
 476	{
 477		llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl;
 478		return;
 479	}
 480	std::string trunc_name(new_name);
 481	LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
 482	LLWearable* new_wearable = LLWearableList::instance().createCopy(
 483		old_wearable,
 484		trunc_name);
 485	LLPointer<LLInventoryCallback> cb =
 486		new addWearableToAgentInventoryCallback(
 487			LLPointer<LLRefCount>(NULL),
 488			type,
 489			index,
 490			new_wearable,
 491			addWearableToAgentInventoryCallback::CALL_WEARITEM);
 492	LLUUID category_id;
 493	if (save_in_lost_and_found)
 494	{
 495		category_id = gInventory.findCategoryUUIDForType(
 496			LLFolderType::FT_LOST_AND_FOUND);
 497	}
 498	else
 499	{
 500		// put in same folder as original
 501		category_id = item->getParentUUID();
 502	}
 503
 504	copy_inventory_item(
 505		gAgent.getID(),
 506		item->getPermissions().getOwner(),
 507		item->getUUID(),
 508		category_id,
 509		new_name,
 510		cb);
 511
 512	// old_wearable may still be referred to by other inventory items. Revert
 513	// unsaved changes so other inventory items aren't affected by the changes
 514	// that were just saved.
 515	old_wearable->revertValues();
 516}
 517
 518void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
 519{
 520	LLWearable* wearable = getWearable(type, index);
 521	llassert(wearable);
 522	if (wearable)
 523	{
 524		wearable->revertValues();
 525	}
 526
 527	gAgent.sendAgentSetAppearance();
 528}
 529
 530void LLAgentWearables::saveAllWearables()
 531{
 532	//if (!gInventory.isLoaded())
 533	//{
 534	//	return;
 535	//}
 536
 537	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 538	{
 539		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 540			saveWearable((LLWearableType::EType)i, j, FALSE);
 541	}
 542	sendAgentWearablesUpdate();
 543}
 544
 545// Called when the user changes the name of a wearable inventory item that is currently being worn.
 546void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& new_name)
 547{
 548	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 549	{
 550		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 551		{
 552			LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
 553			if (curr_item_id == item_id)
 554			{
 555				LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
 556				llassert(old_wearable);
 557				if (!old_wearable) continue;
 558
 559				std::string old_name = old_wearable->getName();
 560				old_wearable->setName(new_name);
 561				LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
 562				new_wearable->setItemID(item_id);
 563				LLInventoryItem* item = gInventory.getItem(item_id);
 564				if (item)
 565				{
 566					new_wearable->setPermissions(item->getPermissions());
 567				}
 568				old_wearable->setName(old_name);
 569
 570				setWearable((LLWearableType::EType)i,j,new_wearable);
 571				sendAgentWearablesUpdate();
 572				break;
 573			}
 574		}
 575	}
 576}
 577
 578
 579BOOL LLAgentWearables::isWearableModifiable(LLWearableType::EType type, U32 index) const
 580{
 581	LLUUID item_id = getWearableItemID(type, index);
 582	return item_id.notNull() ? isWearableModifiable(item_id) : FALSE;
 583}
 584
 585BOOL LLAgentWearables::isWearableModifiable(const LLUUID& item_id) const
 586{
 587	const LLUUID& linked_id = gInventory.getLinkedItemID(item_id);
 588	if (linked_id.notNull())
 589	{
 590		LLInventoryItem* item = gInventory.getItem(linked_id);
 591		if (item && item->getPermissions().allowModifyBy(gAgent.getID(),
 592														 gAgent.getGroupID()))
 593		{
 594			return TRUE;
 595		}
 596	}
 597	return FALSE;
 598}
 599
 600BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index) const
 601{
 602	LLUUID item_id = getWearableItemID(type, index);
 603	if (!item_id.isNull())
 604	{
 605		LLInventoryItem* item = gInventory.getItem(item_id);
 606		if (item && item->getPermissions().allowCopyBy(gAgent.getID(),
 607													   gAgent.getGroupID()))
 608		{
 609			return TRUE;
 610		}
 611	}
 612	return FALSE;
 613}
 614
 615/*
 616  U32 LLAgentWearables::getWearablePermMask(LLWearableType::EType type)
 617  {
 618  LLUUID item_id = getWearableItemID(type);
 619  if (!item_id.isNull())
 620  {
 621  LLInventoryItem* item = gInventory.getItem(item_id);
 622  if (item)
 623  {
 624  return item->getPermissions().getMaskOwner();
 625  }
 626  }
 627  return PERM_NONE;
 628  }
 629*/
 630
 631LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::EType type, U32 index)
 632{
 633	LLUUID item_id = getWearableItemID(type,index);
 634	LLInventoryItem* item = NULL;
 635	if (item_id.notNull())
 636	{
 637		item = gInventory.getItem(item_id);
 638	}
 639	return item;
 640}
 641
 642const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
 643{
 644	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 645	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 646	{
 647		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 648		{
 649			const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
 650			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 651			{
 652				return curr_wearable;
 653			}
 654		}
 655	}
 656	return NULL;
 657}
 658
 659LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 660{
 661	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 662	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 663	{
 664		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 665		{
 666			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
 667			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 668			{
 669				return curr_wearable;
 670			}
 671		}
 672	}
 673	return NULL;
 674}
 675
 676LLWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) 
 677{
 678	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 679	{
 680		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 681		{
 682			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
 683			if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
 684			{
 685				return curr_wearable;
 686			}
 687		}
 688	}
 689	return NULL;
 690}
 691
 692void LLAgentWearables::sendAgentWearablesRequest()
 693{
 694	gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
 695	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
 696	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 697	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 698	gAgent.sendReliableMessage();
 699}
 700
 701// static
 702BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
 703{
 704	return (gAgentWearables.getWearableCount(type) > 0);
 705}
 706
 707LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
 708{
 709	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
 710	if (wearable_iter == mWearableDatas.end())
 711	{
 712		return NULL;
 713	}
 714	wearableentry_vec_t& wearable_vec = wearable_iter->second;
 715	if (index>=wearable_vec.size())
 716	{
 717		return NULL;
 718	}
 719	else
 720	{
 721		return wearable_vec[index];
 722	}
 723}
 724
 725void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
 726{
 727
 728	LLWearable *old_wearable = getWearable(type,index);
 729	if (!old_wearable)
 730	{
 731		pushWearable(type,wearable);
 732		return;
 733	}
 734	
 735	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
 736	if (wearable_iter == mWearableDatas.end())
 737	{
 738		llwarns << "invalid type, type " << type << " index " << index << llendl; 
 739		return;
 740	}
 741	wearableentry_vec_t& wearable_vec = wearable_iter->second;
 742	if (index>=wearable_vec.size())
 743	{
 744		llwarns << "invalid index, type " << type << " index " << index << llendl; 
 745	}
 746	else
 747	{
 748		wearable_vec[index] = wearable;
 749		old_wearable->setLabelUpdated();
 750		wearableUpdated(wearable);
 751		checkWearableAgainstInventory(wearable);
 752	}
 753}
 754
 755U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
 756{
 757	if (wearable == NULL)
 758	{
 759		// no null wearables please!
 760		llwarns << "Null wearable sent for type " << type << llendl;
 761		return MAX_CLOTHING_PER_TYPE;
 762	}
 763	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
 764	{
 765		mWearableDatas[type].push_back(wearable);
 766		wearableUpdated(wearable);
 767		checkWearableAgainstInventory(wearable);
 768		return mWearableDatas[type].size()-1;
 769	}
 770	return MAX_CLOTHING_PER_TYPE;
 771}
 772
 773void LLAgentWearables::wearableUpdated(LLWearable *wearable)
 774{
 775	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
 776	wearable->refreshName();
 777	wearable->setLabelUpdated();
 778
 779	wearable->pullCrossWearableValues();
 780
 781	// Hack pt 2. If the wearable we just loaded has definition version 24,
 782	// then force a re-save of this wearable after slamming the version number to 22.
 783	// This number was incorrectly incremented for internal builds before release, and
 784	// this fix will ensure that the affected wearables are re-saved with the right version number.
 785	// the versions themselves are compatible. This code can be removed before release.
 786	if( wearable->getDefinitionVersion() == 24 )
 787	{
 788		wearable->setDefinitionVersion(22);
 789		U32 index = getWearableIndex(wearable);
 790		llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
 791		saveWearable(wearable->getType(),index,TRUE);
 792	}
 793
 794}
 795
 796void LLAgentWearables::popWearable(LLWearable *wearable)
 797{
 798	if (wearable == NULL)
 799	{
 800		// nothing to do here. move along.
 801		return;
 802	}
 803
 804	U32 index = getWearableIndex(wearable);
 805	LLWearableType::EType type = wearable->getType();
 806
 807	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
 808	{
 809		popWearable(type, index);
 810	}
 811}
 812
 813void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
 814{
 815	LLWearable *wearable = getWearable(type, index);
 816	if (wearable)
 817	{
 818		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
 819		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
 820		wearable->setLabelUpdated();
 821	}
 822}
 823
 824U32	LLAgentWearables::getWearableIndex(const LLWearable *wearable) const
 825{
 826	if (wearable == NULL)
 827	{
 828		return MAX_CLOTHING_PER_TYPE;
 829	}
 830
 831	const LLWearableType::EType type = wearable->getType();
 832	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
 833	if (wearable_iter == mWearableDatas.end())
 834	{
 835		llwarns << "tried to get wearable index with an invalid type!" << llendl;
 836		return MAX_CLOTHING_PER_TYPE;
 837	}
 838	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
 839	for(U32 index = 0; index < wearable_vec.size(); index++)
 840	{
 841		if (wearable_vec[index] == wearable)
 842		{
 843			return index;
 844		}
 845	}
 846
 847	return MAX_CLOTHING_PER_TYPE;
 848}
 849
 850const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
 851{
 852	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
 853	if (wearable_iter == mWearableDatas.end())
 854	{
 855		return NULL;
 856	}
 857	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
 858	if (index>=wearable_vec.size())
 859	{
 860		return NULL;
 861	}
 862	else
 863	{
 864		return wearable_vec[index];
 865	}
 866}
 867
 868LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
 869{
 870	U32 count = getWearableCount(type);
 871	if ( count == 0)
 872	{
 873		return NULL;
 874	}
 875
 876	return getWearable(type, count-1);
 877}
 878
 879LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
 880{
 881	if (getWearableCount(type) == 0)
 882	{
 883		return NULL;
 884	}
 885
 886	return getWearable(type, 0);
 887}
 888
 889U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
 890{
 891	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
 892	if (wearable_iter == mWearableDatas.end())
 893	{
 894		return 0;
 895	}
 896	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
 897	return wearable_vec.size();
 898}
 899
 900U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
 901{
 902	const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
 903	return getWearableCount(wearable_type);
 904}
 905
 906
 907BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
 908{
 909	return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
 910}
 911
 912U32 LLAgentWearables::itemUpdatePendingCount() const
 913{
 914	return mItemsAwaitingWearableUpdate.size();
 915}
 916
 917const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
 918{
 919	const LLWearable *wearable = getWearable(type,index);
 920	if (wearable)
 921		return wearable->getItemID();
 922	else
 923		return LLUUID();
 924}
 925
 926const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
 927{
 928	const LLWearable *wearable = getWearable(type,index);
 929	if (wearable)
 930		return wearable->getAssetID();
 931	else
 932		return LLUUID();
 933}
 934
 935BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const
 936{
 937	return getWearableFromItemID(item_id) != NULL;
 938}
 939
 940// MULTI-WEARABLE: DEPRECATED (see backwards compatibility)
 941// static
 942// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
 943// that viewers have a Current Outfit Folder and won't need this message, and thus
 944// we can remove/ignore this whole function. EXCEPT gAgentWearables.notifyLoadingStarted
 945void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
 946{
 947	// We should only receive this message a single time.  Ignore subsequent AgentWearablesUpdates
 948	// that may result from AgentWearablesRequest having been sent more than once.
 949	if (mInitialWearablesUpdateReceived)
 950		return;
 951
 952	// notify subscribers that wearables started loading. See EXT-7777
 953	// *TODO: find more proper place to not be called from deprecated method.
 954	// Seems such place is found: LLInitialWearablesFetch::processContents()
 955	gAgentWearables.notifyLoadingStarted();
 956
 957	mInitialWearablesUpdateReceived = true;
 958
 959	LLUUID agent_id;
 960	gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
 961
 962	if (isAgentAvatarValid() && (agent_id == gAgentAvatarp->getID()))
 963	{
 964		gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgentQueryManager.mUpdateSerialNum);
 965		
 966		const S32 NUM_BODY_PARTS = 4;
 967		S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData);
 968		if (num_wearables < NUM_BODY_PARTS)
 969		{
 970			// Transitional state.  Avatars should always have at least their body parts (hair, eyes, shape and skin).
 971			// The fact that they don't have any here (only a dummy is sent) implies that either:
 972			// 1. This account existed before we had wearables
 973			// 2. The database has gotten messed up
 974			// 3. This is the account's first login (i.e. the wearables haven't been generated yet).
 975			return;
 976		}
 977
 978		// Get the UUID of the current outfit folder (will be created if it doesn't exist)
 979		const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 980		LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch(current_outfit_id);
 981		
 982		//lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
 983		// Add wearables
 984		// MULTI-WEARABLE: DEPRECATED: Message only supports one wearable per type, will be ignored in future.
 985		gAgentWearables.mItemsAwaitingWearableUpdate.clear();
 986		for (S32 i=0; i < num_wearables; i++)
 987		{
 988			// Parse initial wearables data from message system
 989			U8 type_u8 = 0;
 990			gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i);
 991			if (type_u8 >= LLWearableType::WT_COUNT)
 992			{
 993				continue;
 994			}
 995			const LLWearableType::EType type = (LLWearableType::EType) type_u8;
 996			
 997			LLUUID item_id;
 998			gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i);
 999			
1000			LLUUID asset_id;
1001			gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
1002			if (asset_id.isNull())
1003			{
1004				LLWearable::removeFromAvatar(type, FALSE);
1005			}
1006			else
1007			{
1008				LLAssetType::EType asset_type = LLWearableType::getAssetType(type);
1009				if (asset_type == LLAssetType::AT_NONE)
1010				{
1011					continue;
1012				}
1013				
1014				// MULTI-WEARABLE: DEPRECATED: this message only supports one wearable per type. Should be ignored in future versions
1015				
1016				// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
1017				LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id);
1018				outfit->add(wearable_data);
1019			}
1020			
1021			lldebugs << "       " << LLWearableType::getTypeLabel(type) << llendl;
1022		}
1023		
1024		// Get the complete information on the items in the inventory and set up an observer
1025		// that will trigger when the complete information is fetched.
1026		outfit->startFetch();
1027		if(outfit->isFinished())
1028		{
1029			// everything is already here - call done.
1030			outfit->done();
1031		}
1032		else
1033		{
1034			// it's all on it's way - add an observer, and the inventory
1035			// will call done for us when everything is here.
1036			gInventory.addObserver(outfit);
1037		}
1038		
1039	}
1040}
1041
1042// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the
1043// database.  If for some reason, we can't load one of those assets, we can try to reconstruct it so that
1044// the user isn't left without a shape, for example.  (We can do that only after the inventory has loaded.)
1045void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, U32 index)
1046{
1047	// Try to recover by replacing missing wearable with a new one.
1048	LLNotificationsUtil::add("ReplacedMissingWearable");
1049	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
1050	LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
1051
1052	setWearable(type,index,new_wearable);
1053	//new_wearable->writeToAvatar(TRUE);
1054
1055	// Add a new one in the lost and found folder.
1056	// (We used to overwrite the "not found" one, but that could potentially
1057	// destory content.) JC
1058	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
1059	LLPointer<LLInventoryCallback> cb =
1060		new addWearableToAgentInventoryCallback(
1061			LLPointer<LLRefCount>(NULL),
1062			type,
1063			index,
1064			new_wearable,
1065			addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
1066	addWearableToAgentInventory(cb, new_wearable, lost_and_found_id, TRUE);
1067}
1068
1069void LLAgentWearables::recoverMissingWearableDone()
1070{
1071	// Have all the wearables that the avatar was wearing at log-in arrived or been fabricated?
1072	updateWearablesLoaded();
1073	if (areWearablesLoaded())
1074	{
1075		// Make sure that the server's idea of the avatar's wearables actually match the wearables.
1076		gAgent.sendAgentSetAppearance();
1077	}
1078	else
1079	{
1080		gInventory.addChangedMask(LLInventoryObserver::LABEL, LLUUID::null);
1081		gInventory.notifyObservers();
1082	}
1083}
1084
1085void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
1086{
1087	LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
1088	if (!wearable)
1089	{
1090		llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
1091		return;
1092	}
1093	LLLocalTextureObject lto;
1094	wearable->setLocalTextureObject(texture_type, lto);
1095}
1096
1097class OnWearableItemCreatedCB: public LLInventoryCallback
1098{
1099public:
1100	OnWearableItemCreatedCB():
1101		mWearablesAwaitingItems(LLWearableType::WT_COUNT,NULL)
1102	{
1103		llinfos << "created callback" << llendl;
1104	}
1105	/* virtual */ void fire(const LLUUID& inv_item)
1106	{
1107		llinfos << "One item created " << inv_item.asString() << llendl;
1108		LLViewerInventoryItem *item = gInventory.getItem(inv_item);
1109		mItemsToLink.put(item);
1110		updatePendingWearable(inv_item);
1111	}
1112	~OnWearableItemCreatedCB()
1113	{
1114		llinfos << "All items created" << llendl;
1115		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
1116		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
1117												mItemsToLink,
1118												link_waiter);
1119	}
1120	void addPendingWearable(LLWearable *wearable)
1121	{
1122		if (!wearable)
1123		{
1124			llwarns << "no wearable" << llendl;
1125			return;
1126		}
1127		LLWearableType::EType type = wearable->getType();
1128		if (type<LLWearableType::WT_COUNT)
1129		{
1130			mWearablesAwaitingItems[type] = wearable;
1131		}
1132		else
1133		{
1134			llwarns << "invalid type " << type << llendl;
1135		}
1136	}
1137	void updatePendingWearable(const LLUUID& inv_item)
1138	{
1139		LLViewerInventoryItem *item = gInventory.getItem(inv_item);
1140		if (!item)
1141		{
1142			llwarns << "no item found" << llendl;
1143			return;
1144		}
1145		if (!item->isWearableType())
1146		{
1147			llwarns << "non-wearable item found" << llendl;
1148			return;
1149		}
1150		if (item && item->isWearableType())
1151		{
1152			LLWearableType::EType type = item->getWearableType();
1153			if (type < LLWearableType::WT_COUNT)
1154			{
1155				LLWearable *wearable = mWearablesAwaitingItems[type];
1156				if (wearable)
1157					wearable->setItemID(inv_item);
1158			}
1159			else
1160			{
1161				llwarns << "invalid wearable type " << type << llendl;
1162			}
1163		}
1164	}
1165	
1166private:
1167	LLInventoryModel::item_array_t mItemsToLink;
1168	std::vector<LLWearable*> mWearablesAwaitingItems;
1169};
1170
1171void LLAgentWearables::createStandardWearables()
1172{
1173	llwarns << "Creating standard wearables" << llendl;
1174
1175	if (!isAgentAvatarValid()) return;
1176
1177	const BOOL create[LLWearableType::WT_COUNT] = 
1178		{
1179			TRUE,  //LLWearableType::WT_SHAPE
1180			TRUE,  //LLWearableType::WT_SKIN
1181			TRUE,  //LLWearableType::WT_HAIR
1182			TRUE,  //LLWearableType::WT_EYES
1183			TRUE,  //LLWearableType::WT_SHIRT
1184			TRUE,  //LLWearableType::WT_PANTS
1185			TRUE,  //LLWearableType::WT_SHOES
1186			TRUE,  //LLWearableType::WT_SOCKS
1187			FALSE, //LLWearableType::WT_JACKET
1188			FALSE, //LLWearableType::WT_GLOVES
1189			TRUE,  //LLWearableType::WT_UNDERSHIRT
1190			TRUE,  //LLWearableType::WT_UNDERPANTS
1191			FALSE  //LLWearableType::WT_SKIRT
1192		};
1193
1194	LLPointer<LLInventoryCallback> cb = new OnWearableItemCreatedCB;
1195	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
1196	{
1197		if (create[i])
1198		{
1199			llassert(getWearableCount((LLWearableType::EType)i) == 0);
1200			LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
1201			((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
1202			// no need to update here...
1203			LLUUID category_id = LLUUID::null;
1204			create_inventory_item(gAgent.getID(),
1205								  gAgent.getSessionID(),
1206								  category_id,
1207								  wearable->getTransactionID(),
1208								  wearable->getName(),
1209								  wearable->getDescription(),
1210								  wearable->getAssetType(),
1211								  LLInventoryType::IT_WEARABLE,
1212								  wearable->getType(),
1213								  wearable->getPermissions().getMaskNextOwner(),
1214								  cb);
1215		}
1216	}
1217}
1218
1219void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index)
1220{
1221	llinfos << "type " << type << " index " << index << llendl;
1222
1223	if (!isAgentAvatarValid()) return;
1224	gAgentAvatarp->updateVisualParams();
1225}
1226
1227void LLAgentWearables::createStandardWearablesAllDone()
1228{
1229	// ... because sendAgentWearablesUpdate will notify inventory
1230	// observers.
1231	llinfos << "all done?" << llendl;
1232
1233	mWearablesLoaded = TRUE; 
1234	checkWearablesLoaded();
1235	notifyLoadingFinished();
1236	
1237	updateServer();
1238
1239	// Treat this as the first texture entry message, if none received yet
1240	gAgentAvatarp->onFirstTEMessageReceived();
1241}
1242
1243void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
1244{
1245	LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index);
1246	// Open the inventory and select the first item we added.
1247	if (first_item_id.notNull())
1248	{
1249		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
1250		if (active_panel)
1251		{
1252			active_panel->setSelection(first_item_id, TAKE_FOCUS_NO);
1253		}
1254	}
1255}
1256
1257
1258void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
1259												   LLWearable* wearable,
1260												   const LLUUID& category_id,
1261												   BOOL notify)
1262{
1263	create_inventory_item(gAgent.getID(),
1264						  gAgent.getSessionID(),
1265						  category_id,
1266						  wearable->getTransactionID(),
1267						  wearable->getName(),
1268						  wearable->getDescription(),
1269						  wearable->getAssetType(),
1270						  LLInventoryType::IT_WEARABLE,
1271						  wearable->getType(),
1272						  wearable->getPermissions().getMaskNextOwner(),
1273						  cb);
1274}
1275
1276void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index)
1277{
1278	if (gAgent.isTeen() &&
1279		(type == LLWearableType::WT_UNDERSHIRT || type == LLWearableType::WT_UNDERPANTS))
1280	{
1281		// Can't take off underclothing in simple UI mode or on PG accounts
1282		// TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx
1283		return;
1284	}
1285	if (getWearableCount(type) == 0)
1286	{
1287		// no wearables to remove
1288		return;
1289	}
1290
1291	if (do_remove_all)
1292	{
1293		removeWearableFinal(type, do_remove_all, index);
1294	}
1295	else
1296	{
1297		LLWearable* old_wearable = getWearable(type,index);
1298		
1299		if (old_wearable)
1300		{
1301			if (old_wearable->isDirty())
1302			{
1303				LLSD payload;
1304				payload["wearable_type"] = (S32)type;
1305				payload["wearable_index"] = (S32)index;
1306				// Bring up view-modal dialog: Save changes? Yes, No, Cancel
1307				LLNotificationsUtil::add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog);
1308				return;
1309			}
1310			else
1311			{
1312				removeWearableFinal(type, do_remove_all, index);
1313			}
1314		}
1315	}
1316}
1317
1318
1319// static 
1320bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LLSD& response)
1321{
1322	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1323	LLWearableType::EType type = (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger();
1324	S32 index = (S32)notification["payload"]["wearable_index"].asInteger();
1325	switch(option)
1326	{
1327		case 0:  // "Save"
1328			gAgentWearables.saveWearable(type, index);
1329			gAgentWearables.removeWearableFinal(type, false, index);
1330			break;
1331
1332		case 1:  // "Don't Save"
1333			gAgentWearables.removeWearableFinal(type, false, index);
1334			break;
1335
1336		case 2: // "Cancel"
1337			break;
1338
1339		default:
1340			llassert(0);
1341			break;
1342	}
1343	return false;
1344}
1345
1346// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
1347void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, bool do_remove_all, U32 index)
1348{
1349	//LLAgentDumper dumper("removeWearable");
1350	if (do_remove_all)
1351	{
1352		S32 max_entry = mWearableDatas[type].size()-1;
1353		for (S32 i=max_entry; i>=0; i--)
1354		{
1355			LLWearable* old_wearable = getWearable(type,i);
1356			//queryWearableCache(); // moved below
1357			if (old_wearable)
1358			{
1359				popWearable(old_wearable);
1360				old_wearable->removeFromAvatar(TRUE);
1361			}
1362		}
1363		mWearableDatas[type].clear();
1364	}
1365	else
1366	{
1367		LLWearable* old_wearable = getWearable(type, index);
1368		//queryWearableCache(); // moved below
1369
1370		if (old_wearable)
1371		{
1372			popWearable(old_wearable);
1373			old_wearable->removeFromAvatar(TRUE);
1374		}
1375	}
1376
1377	queryWearableCache();
1378
1379	// Update the server
1380	updateServer();
1381	gInventory.notifyObservers();
1382}
1383
1384// Assumes existing wearables are not dirty.
1385void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
1386										 const LLDynamicArray< LLWearable* >& wearables,
1387										 BOOL remove)
1388{
1389	llinfos << "setWearableOutfit() start" << llendl;
1390
1391	// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later
1392	if (remove)
1393	{
1394		// note: shirt is the first non-body part wearable item. Update if wearable order changes.
1395		// This loop should remove all clothing, but not any body parts
1396		for (S32 type = 0; type < (S32)LLWearableType::WT_COUNT; type++)
1397		{
1398			if (LLWearableType::getAssetType((LLWearableType::EType)type) == LLAssetType::AT_CLOTHING)
1399			{
1400				removeWearable((LLWearableType::EType)type, true, 0);
1401			}
1402		}
1403	}
1404
1405	S32 count = wearables.count();
1406	llassert(items.count() == count);
1407
1408	S32 i;
1409	for (i = 0; i < count; i++)
1410	{
1411		LLWearable* new_wearable = wearables[i];
1412		LLPointer<LLInventoryItem> new_item = items[i];
1413
1414		llassert(new_wearable);
1415		if (new_wearable)
1416		{
1417			const LLWearableType::EType type = new_wearable->getType();
1418		
1419			new_wearable->setName(new_item->getName());
1420			new_wearable->setItemID(new_item->getUUID());
1421
1422			if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
1423			{
1424				// exactly one wearable per body part
1425				setWearable(type,0,new_wearable);
1426			}
1427			else
1428			{
1429				pushWearable(type,new_wearable);
1430			}
1431			wearableUpdated(new_wearable);
1432			checkWearableAgainstInventory(new_wearable);
1433		}
1434	}
1435
1436	gInventory.notifyObservers();
1437
1438	if (isAgentAvatarValid())
1439	{
1440		gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
1441		gAgentAvatarp->updateVisualParams();
1442		gAgentAvatarp->invalidateAll();
1443	}
1444
1445	// Start rendering & update the server
1446	mWearablesLoaded = TRUE; 
1447	checkWearablesLoaded();
1448	notifyLoadingFinished();
1449	queryWearableCache();
1450	updateServer();
1451
1452	gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
1453
1454	lldebugs << "setWearableOutfit() end" << llendl;
1455}
1456
1457
1458// User has picked "wear on avatar" from a menu.
1459void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
1460{
1461	//LLAgentDumper dumper("setWearableItem");
1462	if (isWearingItem(new_item->getUUID()))
1463	{
1464		llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl;
1465		return;
1466	}
1467	
1468	const LLWearableType::EType type = new_wearable->getType();
1469
1470	if (!do_append)
1471	{
1472		// Remove old wearable, if any
1473		// MULTI_WEARABLE: hardwired to 0
1474		LLWearable* old_wearable = getWearable(type,0);
1475		if (old_wearable)
1476		{
1477			const LLUUID& old_item_id = old_wearable->getItemID();
1478			if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&
1479				(old_item_id == new_item->getUUID()))
1480			{
1481				lldebugs << "No change to wearable asset and item: " << LLWearableType::getTypeName(type) << llendl;
1482				return;
1483			}
1484			
1485			if (old_wearable->isDirty())
1486			{
1487				// Bring up modal dialog: Save changes? Yes, No, Cancel
1488				LLSD payload;
1489				payload["item_id"] = new_item->getUUID();
1490				LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable));
1491				return;
1492			}
1493		}
1494	}
1495
1496	setWearableFinal(new_item, new_wearable, do_append);
1497}
1498
1499// static 
1500bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
1501{
1502	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
1503	LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
1504	U32 index = gAgentWearables.getWearableIndex(wearable);
1505	if (!new_item)
1506	{
1507		delete wearable;
1508		return false;
1509	}
1510
1511	switch(option)
1512	{
1513		case 0:  // "Save"
1514			gAgentWearables.saveWearable(wearable->getType(),index);
1515			gAgentWearables.setWearableFinal(new_item, wearable);
1516			break;
1517
1518		case 1:  // "Don't Save"
1519			gAgentWearables.setWearableFinal(new_item, wearable);
1520			break;
1521
1522		case 2: // "Cancel"
1523			break;
1524
1525		default:
1526			llassert(0);
1527			break;
1528	}
1529
1530	delete wearable;
1531	return false;
1532}
1533
1534// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
1535// MULTI_WEARABLE: unify code after null objects are gone.
1536void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
1537{
1538	const LLWearableType::EType type = new_wearable->getType();
1539
1540	if (do_append && getWearableItemID(type,0).notNull())
1541	{
1542		new_wearable->setItemID(new_item->getUUID());
1543		mWearableDatas[type].push_back(new_wearable);
1544		llinfos << "Added additional wearable for type " << type
1545				<< " size is now " << mWearableDatas[type].size() << llendl;
1546		checkWearableAgainstInventory(new_wearable);
1547	}
1548	else
1549	{
1550		// Replace the old wearable with a new one.
1551		llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
1552
1553		LLWearable *old_wearable = getWearable(type,0);
1554		LLUUID old_item_id;
1555		if (old_wearable)
1556		{
1557			old_item_id = old_wearable->getItemID();
1558		}
1559		new_wearable->setItemID(new_item->getUUID());
1560		setWearable(type,0,new_wearable);
1561
1562		if (old_item_id.notNull())
1563		{
1564			gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
1565			gInventory.notifyObservers();
1566		}
1567		llinfos << "Replaced current element 0 for type " << type
1568				<< " size is now " << mWearableDatas[type].size() << llendl;
1569	}
1570
1571	//llinfos << "LLVOAvatar::setWearableItem()" << llendl;
1572	queryWearableCache();
1573	//new_wearable->writeToAvatar(TRUE);
1574
1575	updateServer();
1576}
1577
1578void LLAgentWearables::queryWearableCache()
1579{
1580	if (!areWearablesLoaded())
1581	{
1582		return;
1583	}
1584
1585	// Look up affected baked textures.
1586	// If they exist:
1587	//		disallow updates for affected layersets (until dataserver responds with cache request.)
1588	//		If cache miss, turn updates back on and invalidate composite.
1589	//		If cache hit, modify baked texture entries.
1590	//
1591	// Cache requests contain list of hashes for each baked texture entry.
1592	// Response is list of valid baked texture assets. (same message)
1593
1594	gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture);
1595	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
1596	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
1597	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
1598	gMessageSystem->addS32Fast(_PREHASH_SerialNum, gAgentQueryManager.mWearablesCacheQueryID);
1599
1600	S32 num_queries = 0;
1601	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
1602	{
1603		LLUUID hash_id = computeBakedTextureHash((EBakedTextureIndex) baked_index);
1604		if (hash_id.notNull())
1605		{
1606			num_queries++;
1607			// *NOTE: make sure at least one request gets packed
1608
1609			ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
1610
1611			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
1612			gMessageSystem->nextBlockFast(_PREHASH_WearableData);
1613			gMessageSystem->addUUIDFast(_PREHASH_ID, hash_id);
1614			gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)te_index);
1615		}
1616
1617		gAgentQueryManager.mActiveCacheQueries[baked_index] = gAgentQueryManager.mWearablesCacheQueryID;
1618	}
1619	//VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout
1620	if(gAgent.getRegion())
1621	{
1622		llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
1623		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
1624		gAgentQueryManager.mNumPendingQueries++;
1625		gAgentQueryManager.mWearablesCacheQueryID++;
1626	}
1627}
1628
1629LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
1630												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
1631{
1632	LLUUID hash_id;
1633	bool hash_computed = false;
1634	LLMD5 hash;
1635	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
1636
1637	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
1638	{
1639		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
1640		const U32 num_wearables = getWearableCount(baked_type);
1641		for (U32 index = 0; index < num_wearables; ++index)
1642		{
1643			const LLWearable* wearable = getWearable(baked_type,index);
1644			if (wearable)
1645			{
1646				LLUUID asset_id = wearable->getAssetID();
1647				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
1648				hash_computed = true;
1649			}
1650		}
1651	}
1652	if (hash_computed)
1653	{
1654		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
1655
1656		// Add some garbage into the hash so that it becomes invalid.
1657		if (!generate_valid_hash)
1658		{
1659			if (isAgentAvatarValid())
1660			{
1661				hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
1662			}
1663		}
1664		hash.finalize();
1665		hash.raw_digest(hash_id.mData);
1666	}
1667
1668	return hash_id;
1669}
1670
1671// User has picked "remove from avatar" from a menu.
1672// static
1673void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
1674{
1675	if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
1676		//!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
1677	{
1678		gAgentWearables.removeWearable(type,false,index);
1679	}
1680}
1681
1682//static 
1683void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &type)
1684{
1685	if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
1686		//!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
1687	{
1688		gAgentWearables.removeWearable(type,true,0);
1689	}
1690}
1691
1692// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() l…

Large files files are truncated, but you can click here to view the full file