/indra/newview/llagentwearables.cpp
C++ | 2081 lines | 1614 code | 245 blank | 222 comment | 273 complexity | 4fe5f617409047e528a25ad5b73075c3 MD5 | raw file
Possible License(s): LGPL-2.1
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() logic to 1693// get attachments into desired state with minimal number of adds/removes. 1694void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array) 1695{ 1696 // Possible cases: 1697 // already wearing but not in request set -> take off. 1698 // already wearing and in request set -> leave alone. 1699 // not wearing and in request set -> put on. 1700 1701 if (!isAgentAvatarValid()) return; 1702 1703 std::set<LLUUID> requested_item_ids; 1704 std::set<LLUUID> current_item_ids; 1705 for (S32 i=0; i<obj_item_array.count(); i++) 1706 requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID()); 1707 1708 // Build up list of objects to be removed and items currently attached. 1709 llvo_vec_t objects_to_remove; 1710 for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 1711 iter != gAgentAvatarp->mAttachmentPoints.end();) 1712 { 1713 LLVOAvatar::attachment_map_t::iterator curiter = iter++; 1714 LLViewerJointAttachment* attachment = curiter->second; 1715 for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); 1716 attachment_iter != attachment->mAttachedObjects.end(); 1717 ++attachment_iter) 1718 { 1719 LLViewerObject *objectp = (*attachment_iter); 1720 if (objectp) 1721 { 1722 LLUUID object_item_id = objectp->getAttachmentItemID(); 1723 if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) 1724 { 1725 // Object currently worn, was requested. 1726 // Flag as currently worn so we won't have to add it again. 1727 current_item_ids.insert(object_item_id); 1728 } 1729 else 1730 { 1731 // object currently worn, not requested. 1732 objects_to_remove.push_back(objectp); 1733 } 1734 } 1735 } 1736 } 1737 1738 LLInventoryModel::item_array_t items_to_add; 1739 for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin(); 1740 it != obj_item_array.end(); 1741 ++it) 1742 { 1743 LLUUID linked_id = (*it).get()->getLinkedUUID(); 1744 if (current_item_ids.find(linked_id) != current_item_ids.end()) 1745 { 1746 // Requested attachment is already worn. 1747 } 1748 else 1749 { 1750 // Requested attachment is not worn yet. 1751 items_to_add.push_back(*it); 1752 } 1753 } 1754 // S32 remove_count = objects_to_remove.size(); 1755 // S32 add_count = items_to_add.size(); 1756 // llinfos << "remove " << remove_count << " add " << add_count << llendl; 1757 1758 // Remove everything in objects_to_remove 1759 userRemoveMultipleAttachments(objects_to_remove); 1760 1761 // Add everything in items_to_add 1762 userAttachMultipleAttachments(items_to_add); 1763} 1764 1765void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) 1766{ 1767 if (!isAgentAvatarValid()) return; 1768 1769 if (objects_to_remove.empty()) 1770 return; 1771 1772 gMessageSystem->newMessage("ObjectDetach"); 1773 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 1774 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 1775 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 1776 1777 for (llvo_vec_t::iterator it = objects_to_remove.begin(); 1778 it != objects_to_remove.end(); 1779 ++it) 1780 { 1781 LLViewerObject *objectp = *it; 1782 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 1783 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); 1784 } 1785 gMessageSystem->sendReliable(gAgent.getRegionHost()); 1786} 1787 1788void LLAgentWearables::userRemoveAllAttachments() 1789{ 1790 if (!isAgentAvatarValid()) return; 1791 1792 llvo_vec_t objects_to_remove; 1793 1794 for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 1795 iter != gAgentAvatarp->mAttachmentPoints.end();) 1796 { 1797 LLVOAvatar::attachment_map_t::iterator curiter = iter++; 1798 LLViewerJointAttachment* attachment = curiter->second; 1799 for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); 1800 attachment_iter != attachment->mAttachedObjects.end(); 1801 ++attachment_iter) 1802 { 1803 LLViewerObject *attached_object = (*attachment_iter); 1804 if (attached_object) 1805 { 1806 objects_to_remove.push_back(attached_object); 1807 } 1808 } 1809 } 1810 userRemoveMultipleAttachments(objects_to_remove); 1811} 1812 1813void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) 1814{ 1815 // Build a compound message to send all the objects that need to be rezzed. 1816 S32 obj_count = obj_item_array.count(); 1817 1818 // Limit number of packets to send 1819 const S32 MAX_PACKETS_TO_SEND = 10; 1820 const S32 OBJECTS_PER_PACKET = 4; 1821 const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; 1822 if( obj_count > MAX_OBJECTS_TO_SEND ) 1823 { 1824 obj_count = MAX_OBJECTS_TO_SEND; 1825 } 1826 1827 // Create an id to keep the parts of the compound message together 1828 LLUUID compound_msg_id; 1829 compound_msg_id.generate(); 1830 LLMessageSystem* msg = gMessageSystem; 1831 1832 for(S32 i = 0; i < obj_count; ++i) 1833 { 1834 if( 0 == (i % OBJECTS_PER_PACKET) ) 1835 { 1836 // Start a new message chunk 1837 msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); 1838 msg->nextBlockFast(_PREHASH_AgentData); 1839 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 1840 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 1841 msg->nextBlockFast(_PREHASH_HeaderData); 1842 msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); 1843 msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); 1844 msg->addBOOLFast(_PREHASH_FirstDetachAll, false ); 1845 } 1846 1847 const LLInventoryItem* item = obj_item_array.get(i).get(); 1848 msg->nextBlockFast(_PREHASH_ObjectData ); 1849 msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); 1850 msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); 1851 msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD); // Wear at the previous or default attachment point 1852 pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); 1853 msg->addStringFast(_PREHASH_Name, item->getName()); 1854 msg->addStringFast(_PREHASH_Description, item->getDescription()); 1855 1856 if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) 1857 { 1858 // End of message chunk 1859 msg->sendReliable( gAgent.getRegion()->getHost() ); 1860 } 1861 } 1862} 1863 1864void LLAgentWearables::checkWearablesLoaded() const 1865{ 1866#ifdef SHOW_ASSERT 1867 U32 item_pend_count = itemUpdatePendingCount(); 1868 if (mWearablesLoaded) 1869 { 1870 llassert(item_pend_count==0); 1871 } 1872#endif 1873} 1874 1875// Returns false if the given wearable is already topmost/bottommost 1876// (depending on closer_to_body parameter). 1877bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) 1878{ 1879 const LLWearable* wearable = getWearableFromItemID(item_id); 1880 if (!wearable) return false; 1881 1882 LLWearableType::EType wtype = wearable->getType(); 1883 const LLWearable* marginal_wearable = closer_to_body ? getBottomWearable(wtype) : getTopWearable(wtype); 1884 if (!marginal_wearable) return false; 1885 1886 return wearable != marginal_wearable; 1887} 1888 1889BOOL LLAgentWearables::areWearablesLoaded() const 1890{ 1891 checkWearablesLoaded(); 1892 return mWearablesLoaded; 1893} 1894 1895// MULTI-WEARABLE: DEPRECATED: item pending count relies on old messages that don't support multi-wearables. do not trust to be accurate 1896void LLAgentWearables::updateWearablesLoaded() 1897{ 1898 mWearablesLoaded = (itemUpdatePendingCount()==0); 1899 if (mWearablesLoaded) 1900 { 1901 notifyLoadingFinished(); 1902 } 1903} 1904 1905bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const 1906{ 1907 if (!wearable) return false; 1908 1909 LLWearableType::EType type = wearable->getType(); 1910 // Make sure the user always has at least one shape, skin, eyes, and hair type currently worn. 1911 return !(((type == LLWearableType::WT_SHAPE) || (type == LLWearableType::WT_SKIN) || (type == LLWearableType::WT_HAIR) || (type == LLWearableType::WT_EYES)) 1912 && (getWearableCount(type) <= 1) ); 1913} 1914void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake) 1915{ 1916 for( S32 type = 0; type < LLWearableType::WT_COUNT; ++type ) 1917 { 1918 for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) 1919 { 1920 LLWearable *wearable = getWearable((LLWearableType::EType)type,count); 1921 llassert(wearable); 1922 if (wearable) 1923 { 1924 wearable->animateParams(delta, upload_bake); 1925 } 1926 } 1927 } 1928} 1929 1930bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool closer_to_body) 1931{ 1932 if (!item) return false; 1933 if (!item->isWearableType()) return false; 1934 1935 wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType()); 1936 if (wearable_iter == mWearableDatas.end()) return false; 1937 1938 wearableentry_vec_t& wearable_vec = wearable_iter->second; 1939 if (wearable_vec.empty()) return false; 1940 1941 const LLUUID& asset_id = item->getAssetUUID(); 1942 1943 //nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body) 1944 if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false; 1945 if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false; 1946 1947 for (U32 i = 0; i < wearable_vec.size(); ++i) 1948 { 1949 LLWearable* wearable = wearable_vec[i]; 1950 if (!wearable) continue; 1951 if (wearable->getAssetID() != asset_id) continue; 1952 1953 //swapping wearables 1954 U32 swap_i = closer_to_body ? i-1 : i+1; 1955 wearable_vec[i] = wearable_vec[swap_i]; 1956 wearable_vec[swap_i] = wearable; 1957 return true; 1958 } 1959 1960 return false; 1961} 1962 1963// static 1964void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id) 1965{ 1966 if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; 1967 1968 LLWearable* wearable = LLWearableList::instance().createNewWearable(type); 1969 LLAssetType::EType asset_type = wearable->getAssetType(); 1970 LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; 1971 LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL; 1972 LLUUID folder_id; 1973 1974 if (parent_id.notNull()) 1975 { 1976 folder_id = parent_id; 1977 } 1978 else 1979 { 1980 LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type); 1981 folder_id = gInventory.findCategoryUUIDForType(folder_type); 1982 } 1983 1984 create_inventory_item(gAgent.getID(), gAgent.getSessionID(), 1985 folder_id, wearable->getTransactionID(), wearable->getName(), 1986 wearable->getDescription(), asset_type, inv_type, wearable->getType(), 1987 wearable->getPermissions().getMaskNextOwner(), 1988 cb); 1989} 1990 1991// static 1992void LLAgentWearables::editWearable(const LLUUID& item_id) 1993{ 1994 LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); 1995 if (!item) 1996 { 1997 llwarns << "Failed to get linked item" << llendl; 1998 return; 1999 } 2000 2001 LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); 2002 if (!wearable) 2003 { 2004 llwarns << "Cannot get wearable" << llendl; 2005 return; 2006 } 2007 2008 if (!gAgentWearables.isWearableModifiable(item->getUUID())) 2009 { 2010 llwarns << "Cannot modify wearable" << llendl; 2011 return; 2012 } 2013 2014 const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType()); 2015 LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance"); 2016 LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch); 2017} 2018 2019// Request editing the item after it gets worn. 2020void LLAgentWearables::requestEditingWearable(const LLUUID& item_id) 2021{ 2022 mItemToEdit = gInventory.getLinkedItemID(item_id); 2023} 2024 2025// Start editing the item if previously requested. 2026void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id) 2027{ 2028 if (mItemToEdit.notNull() && 2029 mItemToEdit == gInventory.getLinkedItemID(item_id)) 2030 { 2031 LLAgentWearables::editWearable(item_id); 2032 mItemToEdit.setNull(); 2033 } 2034} 2035 2036void LLAgentWearables::updateServer() 2037{ 2038 sendAgentWearablesUpdate(); 2039 gAgent.sendAgentSetAppearance(); 2040} 2041 2042void LLAgentWearables::populateMyOutfitsFolder(void) 2043{ 2044 llinfos << "starting outfit population" << llendl; 2045 2046 const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); 2047 LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(my_outfits_id); 2048 outfits->mMyOutfitsID = my_outfits_id; 2049 2050 // Get the complete information on the items in the inventory and 2051 // setup an observer that will wait for that to happen. 2052 gInventory.addObserver(outfits); 2053 outfits->startFetch(); 2054 if (outfits->isFinished()) 2055 { 2056 outfits->done(); 2057 } 2058} 2059 2060boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb) 2061{ 2062 return mLoadingStartedSignal.connect(cb); 2063} 2064 2065boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb) 2066{ 2067 return mLoadedSignal.connect(cb); 2068} 2069 2070void LLAgentWearables::notifyLoadingStarted() 2071{ 2072 mCOFChangeInProgress = true; 2073 mLoadingStartedSignal(); 2074} 2075 2076void LLAgentWearables::notifyLoadingFinished() 2077{ 2078 mCOFChangeInProgress = false; 2079 mLoadedSignal(); 2080} 2081// EOF