00001
00032 #include "llviewerprecompiledheaders.h"
00033 #include "llviewerinventory.h"
00034
00035 #include "message.h"
00036 #include "indra_constants.h"
00037
00038 #include "llagent.h"
00039 #include "llviewercontrol.h"
00040 #include "llconsole.h"
00041 #include "llinventorymodel.h"
00042 #include "llnotify.h"
00043 #include "llimview.h"
00044 #include "llgesturemgr.h"
00045
00046 #include "llinventoryview.h"
00047
00048 #include "llviewerregion.h"
00049 #include "llviewerobjectlist.h"
00050 #include "llpreviewgesture.h"
00051 #include "llviewerwindow.h"
00052
00056
00060
00061 LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& uuid,
00062 const LLUUID& parent_uuid,
00063 const LLPermissions& perm,
00064 const LLUUID& asset_uuid,
00065 LLAssetType::EType type,
00066 LLInventoryType::EType inv_type,
00067 const LLString& name,
00068 const LLString& desc,
00069 const LLSaleInfo& sale_info,
00070 U32 flags,
00071 S32 creation_date_utc) :
00072 LLInventoryItem(uuid, parent_uuid, perm, asset_uuid, type, inv_type,
00073 name, desc, sale_info, flags, creation_date_utc),
00074 mIsComplete(TRUE)
00075 {
00076 }
00077
00078 LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& item_id,
00079 const LLUUID& parent_id,
00080 const char* name,
00081 LLInventoryType::EType inv_type) :
00082 LLInventoryItem(),
00083 mIsComplete(FALSE)
00084 {
00085 mUUID = item_id;
00086 mParentUUID = parent_id;
00087 mInventoryType = inv_type;
00088 mName.assign(name);
00089 }
00090
00091 LLViewerInventoryItem::LLViewerInventoryItem() :
00092 LLInventoryItem(),
00093 mIsComplete(FALSE)
00094 {
00095 }
00096
00097 LLViewerInventoryItem::LLViewerInventoryItem(const LLViewerInventoryItem* other) :
00098 LLInventoryItem()
00099 {
00100 copyViewerItem(other);
00101 if (!mIsComplete)
00102 {
00103 llwarns << "LLViewerInventoryItem copy constructor for incomplete item"
00104 << mUUID << llendl;
00105 }
00106 }
00107
00108 LLViewerInventoryItem::LLViewerInventoryItem(const LLInventoryItem *other) :
00109 LLInventoryItem(other),
00110 mIsComplete(TRUE)
00111 {
00112 }
00113
00114
00115 LLViewerInventoryItem::~LLViewerInventoryItem()
00116 {
00117 }
00118
00119 void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other)
00120 {
00121 LLInventoryItem::copyItem(other);
00122 mIsComplete = other->mIsComplete;
00123 mTransactionID = other->mTransactionID;
00124 }
00125
00126
00127 void LLViewerInventoryItem::copyItem(const LLInventoryItem *other)
00128 {
00129 LLInventoryItem::copyItem(other);
00130 mIsComplete = true;
00131 mTransactionID.setNull();
00132 }
00133
00134 void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& newitem) const
00135 {
00136 newitem = new LLViewerInventoryItem(this);
00137 if(newitem.notNull())
00138 {
00139 LLUUID item_id;
00140 item_id.generate();
00141 newitem->setUUID(item_id);
00142 }
00143 }
00144
00145 void LLViewerInventoryItem::removeFromServer()
00146 {
00147 llinfos << "Removing inventory item " << mUUID << " from server."
00148 << llendl;
00149
00150 LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
00151 gInventory.accountForUpdate(up);
00152
00153 LLMessageSystem* msg = gMessageSystem;
00154 msg->newMessageFast(_PREHASH_RemoveInventoryItem);
00155 msg->nextBlockFast(_PREHASH_AgentData);
00156 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00157 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00158 msg->nextBlockFast(_PREHASH_InventoryData);
00159 msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00160 gAgent.sendReliableMessage();
00161 }
00162
00163 void LLViewerInventoryItem::updateServer(BOOL is_new) const
00164 {
00165 if(!mIsComplete)
00166 {
00167
00168
00169 llerrs << "LLViewerInventoryItem::updateServer() - for incomplete item"
00170 << llendl;
00171 return;
00172 }
00173 if(gAgent.getID() != mPermissions.getOwner())
00174 {
00175
00176 llwarns << "LLViewerInventoryItem::updateServer() - for unowned item"
00177 << llendl;
00178 return;
00179 }
00180 LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
00181 gInventory.accountForUpdate(up);
00182
00183 LLMessageSystem* msg = gMessageSystem;
00184 msg->newMessageFast(_PREHASH_UpdateInventoryItem);
00185 msg->nextBlockFast(_PREHASH_AgentData);
00186 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00187 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00188 msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
00189 msg->nextBlockFast(_PREHASH_InventoryData);
00190 msg->addU32Fast(_PREHASH_CallbackID, 0);
00191 packMessage(msg);
00192 gAgent.sendReliableMessage();
00193 }
00194
00195 void LLViewerInventoryItem::fetchFromServer(void) const
00196 {
00197 if(!mIsComplete)
00198 {
00199 LLMessageSystem* msg = gMessageSystem;
00200 msg->newMessage("FetchInventory");
00201 msg->nextBlock("AgentData");
00202 msg->addUUID("AgentID", gAgent.getID());
00203 msg->addUUID("SessionID", gAgent.getSessionID());
00204 msg->nextBlock("InventoryData");
00205 msg->addUUID("OwnerID", mPermissions.getOwner());
00206 msg->addUUID("ItemID", mUUID);
00207 gAgent.sendReliableMessage();
00208 }
00209 else
00210 {
00211
00212 llwarns << "request to fetch complete item" << llendl;
00213 }
00214 }
00215
00216
00217 BOOL LLViewerInventoryItem::unpackMessage(LLSD item)
00218 {
00219 BOOL rv = LLInventoryItem::fromLLSD(item);
00220 mIsComplete = TRUE;
00221 return rv;
00222 }
00223
00224
00225 BOOL LLViewerInventoryItem::unpackMessage(
00226 LLMessageSystem* msg, const char* block, S32 block_num)
00227 {
00228 BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
00229 mIsComplete = TRUE;
00230 return rv;
00231 }
00232
00233 void LLViewerInventoryItem::setTransactionID(const LLTransactionID& transaction_id)
00234 {
00235 mTransactionID = transaction_id;
00236 }
00237
00238 void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const
00239 {
00240 msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00241 msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
00242 mPermissions.packMessage(msg);
00243 msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
00244 S8 type = static_cast<S8>(mType);
00245 msg->addS8Fast(_PREHASH_Type, type);
00246 type = static_cast<S8>(mInventoryType);
00247 msg->addS8Fast(_PREHASH_InvType, type);
00248 msg->addU32Fast(_PREHASH_Flags, mFlags);
00249 mSaleInfo.packMessage(msg);
00250 msg->addStringFast(_PREHASH_Name, mName);
00251 msg->addStringFast(_PREHASH_Description, mDescription);
00252 msg->addS32Fast(_PREHASH_CreationDate, mCreationDate);
00253 U32 crc = getCRC32();
00254 msg->addU32Fast(_PREHASH_CRC, crc);
00255 }
00256
00257 BOOL LLViewerInventoryItem::importFile(LLFILE* fp)
00258 {
00259 BOOL rv = LLInventoryItem::importFile(fp);
00260 mIsComplete = TRUE;
00261 return rv;
00262 }
00263
00264
00265 BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
00266 {
00267 BOOL rv = LLInventoryItem::importLegacyStream(input_stream);
00268 mIsComplete = TRUE;
00269 return rv;
00270 }
00271
00272 bool LLViewerInventoryItem::importFileLocal(LLFILE* fp)
00273 {
00274
00275 bool rv = (LLInventoryItem::importFile(fp) ? true : false);
00276 mIsComplete = false;
00277 return rv;
00278 }
00279
00280 bool LLViewerInventoryItem::exportFileLocal(LLFILE* fp) const
00281 {
00282 char uuid_str[UUID_STR_LENGTH];
00283 fprintf(fp, "\tinv_item\t0\n\t{\n");
00284 mUUID.toString(uuid_str);
00285 fprintf(fp, "\t\titem_id\t%s\n", uuid_str);
00286 mParentUUID.toString(uuid_str);
00287 fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00288 mPermissions.exportFile(fp);
00289 fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00290 const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
00291 if(inv_type_str) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str);
00292 fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00293 fprintf(fp, "\t\tcreation_date\t%d\n", mCreationDate);
00294 fprintf(fp,"\t}\n");
00295 return true;
00296 }
00297
00298 void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
00299 {
00300 LLMessageSystem* msg = gMessageSystem;
00301 msg->newMessageFast(_PREHASH_MoveInventoryItem);
00302 msg->nextBlockFast(_PREHASH_AgentData);
00303 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00304 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00305 msg->addBOOLFast(_PREHASH_Stamp, restamp);
00306 msg->nextBlockFast(_PREHASH_InventoryData);
00307 msg->addUUIDFast(_PREHASH_ItemID, mUUID);
00308 msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
00309 msg->addString("NewName", NULL);
00310 gAgent.sendReliableMessage();
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00326
00327 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& uuid,
00328 const LLUUID& parent_uuid,
00329 LLAssetType::EType pref,
00330 const LLString& name,
00331 const LLUUID& owner_id) :
00332 LLInventoryCategory(uuid, parent_uuid, pref, name),
00333 mOwnerID(owner_id),
00334 mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
00335 mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
00336 {
00337 mDescendentsRequested.reset();
00338 }
00339
00340 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) :
00341 mOwnerID(owner_id),
00342 mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
00343 mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
00344 {
00345 mDescendentsRequested.reset();
00346 }
00347
00348 LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other)
00349 {
00350 copyViewerCategory(other);
00351 }
00352
00353 LLViewerInventoryCategory::~LLViewerInventoryCategory()
00354 {
00355 }
00356
00357 void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCategory* other)
00358 {
00359 copyCategory(other);
00360 mOwnerID = other->mOwnerID;
00361 mVersion = other->mVersion;
00362 mDescendentCount = other->mDescendentCount;
00363 mDescendentsRequested = other->mDescendentsRequested;
00364 }
00365
00366
00367 void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const
00368 {
00369 LLMessageSystem* msg = gMessageSystem;
00370 msg->newMessageFast(_PREHASH_MoveInventoryFolder);
00371 msg->nextBlockFast(_PREHASH_AgentData);
00372 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00373 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00374
00375 msg->addBOOL("Stamp", restamp);
00376 msg->nextBlockFast(_PREHASH_InventoryData);
00377 msg->addUUIDFast(_PREHASH_FolderID, mUUID);
00378 msg->addUUIDFast(_PREHASH_ParentID, mParentUUID);
00379 gAgent.sendReliableMessage();
00380 }
00381
00382 void LLViewerInventoryCategory::updateServer(BOOL is_new) const
00383 {
00384
00385 if(LLAssetType::AT_NONE != mPreferredType)
00386 {
00387 LLNotifyBox::showXml("CannotModifyProtectedCategories");
00388 return;
00389 }
00390
00391 LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
00392 gInventory.accountForUpdate(up);
00393
00394 LLMessageSystem* msg = gMessageSystem;
00395 msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
00396 msg->nextBlockFast(_PREHASH_AgentData);
00397 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00398 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00399 msg->nextBlockFast(_PREHASH_FolderData);
00400 packMessage(msg);
00401 gAgent.sendReliableMessage();
00402 }
00403
00404 void LLViewerInventoryCategory::removeFromServer( void )
00405 {
00406 llinfos << "Removing inventory category " << mUUID << " from server."
00407 << llendl;
00408
00409 if(LLAssetType::AT_NONE != mPreferredType)
00410 {
00411 LLNotifyBox::showXml("CannotRemoveProtectedCategories");
00412 return;
00413 }
00414
00415 LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
00416 gInventory.accountForUpdate(up);
00417
00418 LLMessageSystem* msg = gMessageSystem;
00419 msg->newMessageFast(_PREHASH_RemoveInventoryFolder);
00420 msg->nextBlockFast(_PREHASH_AgentData);
00421 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00422 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00423 msg->nextBlockFast(_PREHASH_FolderData);
00424 msg->addUUIDFast(_PREHASH_FolderID, mUUID);
00425 gAgent.sendReliableMessage();
00426 }
00427
00428 bool LLViewerInventoryCategory::fetchDescendents()
00429 {
00430 if((VERSION_UNKNOWN == mVersion)
00431 && mDescendentsRequested.hasExpired())
00432 {
00433 const F32 FETCH_TIMER_EXPIRY = 10.0f;
00434 mDescendentsRequested.reset();
00435 mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY);
00436
00437
00438
00439
00440
00441
00442 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
00443
00444 std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents");
00445
00446 if (!url.empty())
00447 {
00448 LLInventoryModel::startBackgroundFetch(mUUID);
00449 }
00450 else
00451 {
00452 llinfos << "FetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl;
00453 LLMessageSystem* msg = gMessageSystem;
00454 msg->newMessage("FetchInventoryDescendents");
00455 msg->nextBlock("AgentData");
00456 msg->addUUID("AgentID", gAgent.getID());
00457 msg->addUUID("SessionID", gAgent.getSessionID());
00458 msg->nextBlock("InventoryData");
00459 msg->addUUID("FolderID", mUUID);
00460 msg->addUUID("OwnerID", mOwnerID);
00461
00462 msg->addS32("SortOrder", sort_order);
00463 msg->addBOOL("FetchFolders", FALSE);
00464 msg->addBOOL("FetchItems", TRUE);
00465 gAgent.sendReliableMessage();
00466 }
00467 return true;
00468 }
00469 return false;
00470 }
00471
00472 bool LLViewerInventoryCategory::importFileLocal(LLFILE* fp)
00473 {
00474
00475 char buffer[MAX_STRING];
00476 char keyword[MAX_STRING];
00477 char valuestr[MAX_STRING];
00478
00479 keyword[0] = '\0';
00480 valuestr[0] = '\0';
00481 while(!feof(fp))
00482 {
00483 if (fgets(buffer, MAX_STRING, fp) == NULL)
00484 {
00485 buffer[0] = '\0';
00486 }
00487
00488 sscanf(
00489 buffer, " %254s %254s", keyword, valuestr);
00490 if(0 == strcmp("{",keyword))
00491 {
00492 continue;
00493 }
00494 if(0 == strcmp("}", keyword))
00495 {
00496 break;
00497 }
00498 else if(0 == strcmp("cat_id", keyword))
00499 {
00500 mUUID.set(valuestr);
00501 }
00502 else if(0 == strcmp("parent_id", keyword))
00503 {
00504 mParentUUID.set(valuestr);
00505 }
00506 else if(0 == strcmp("type", keyword))
00507 {
00508 mType = LLAssetType::lookup(valuestr);
00509 }
00510 else if(0 == strcmp("pref_type", keyword))
00511 {
00512 mPreferredType = LLAssetType::lookup(valuestr);
00513 }
00514 else if(0 == strcmp("name", keyword))
00515 {
00516
00517
00518 sscanf(
00519 buffer, " %254s %254[^|]", keyword, valuestr);
00520 mName.assign(valuestr);
00521 LLString::replaceNonstandardASCII(mName, ' ');
00522 LLString::replaceChar(mName, '|', ' ');
00523 }
00524 else if(0 == strcmp("owner_id", keyword))
00525 {
00526 mOwnerID.set(valuestr);
00527 }
00528 else if(0 == strcmp("version", keyword))
00529 {
00530 sscanf(valuestr, "%d", &mVersion);
00531 }
00532 else
00533 {
00534 llwarns << "unknown keyword '" << keyword
00535 << "' in inventory import category " << mUUID << llendl;
00536 }
00537 }
00538 return true;
00539 }
00540
00541 bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
00542 {
00543 char uuid_str[UUID_STR_LENGTH];
00544 fprintf(fp, "\tinv_category\t0\n\t{\n");
00545 mUUID.toString(uuid_str);
00546 fprintf(fp, "\t\tcat_id\t%s\n", uuid_str);
00547 mParentUUID.toString(uuid_str);
00548 fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
00549 fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
00550 fprintf(fp, "\t\tpref_type\t%s\n", LLAssetType::lookup(mPreferredType));
00551 fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
00552 mOwnerID.toString(uuid_str);
00553 fprintf(fp, "\t\towner_id\t%s\n", uuid_str);
00554 fprintf(fp, "\t\tversion\t%d\n", mVersion);
00555 fprintf(fp,"\t}\n");
00556 return true;
00557 }
00558
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 LLInventoryCallbackManager *LLInventoryCallbackManager::sInstance = NULL;
00575
00576 LLInventoryCallbackManager::LLInventoryCallbackManager() :
00577 mLastCallback(0)
00578 {
00579 if( sInstance != NULL )
00580 {
00581 llwarns << "LLInventoryCallbackManager::LLInventoryCallbackManager: unexpected multiple instances" << llendl;
00582 return;
00583 }
00584 sInstance = this;
00585 }
00586
00587 LLInventoryCallbackManager::~LLInventoryCallbackManager()
00588 {
00589 if( sInstance != this )
00590 {
00591 llwarns << "LLInventoryCallbackManager::~LLInventoryCallbackManager: unexpected multiple instances" << llendl;
00592 return;
00593 }
00594 sInstance = NULL;
00595 }
00596
00597 U32 LLInventoryCallbackManager::registerCB(LLPointer<LLInventoryCallback> cb)
00598 {
00599 if (cb.isNull())
00600 return 0;
00601
00602 mLastCallback++;
00603 if (!mLastCallback)
00604 mLastCallback++;
00605
00606 mMap[mLastCallback] = cb;
00607 return mLastCallback;
00608 }
00609
00610 void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
00611 {
00612 if (!callback_id || item_id.isNull())
00613 return;
00614
00615 std::map<U32, LLPointer<LLInventoryCallback> >::iterator i;
00616
00617 i = mMap.find(callback_id);
00618 if (i != mMap.end())
00619 {
00620 (*i).second->fire(item_id);
00621 mMap.erase(i);
00622 }
00623 }
00624
00625 void WearOnAvatarCallback::fire(const LLUUID& inv_item)
00626 {
00627 if (inv_item.isNull())
00628 return;
00629
00630 LLViewerInventoryItem *item = gInventory.getItem(inv_item);
00631 if (item)
00632 {
00633 wear_inventory_item_on_avatar(item);
00634 }
00635 }
00636
00637 RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
00638 {
00639 mAttach = attachmentp;
00640 }
00641 RezAttachmentCallback::~RezAttachmentCallback()
00642 {
00643 }
00644
00645 void RezAttachmentCallback::fire(const LLUUID& inv_item)
00646 {
00647 if (inv_item.isNull())
00648 return;
00649
00650 LLViewerInventoryItem *item = gInventory.getItem(inv_item);
00651 if (item)
00652 {
00653 rez_attachment(item, mAttach);
00654 }
00655 }
00656
00657 extern LLGestureManager gGestureManager;
00658 void ActivateGestureCallback::fire(const LLUUID& inv_item)
00659 {
00660 if (inv_item.isNull())
00661 return;
00662
00663 gGestureManager.activateGesture(inv_item);
00664 }
00665
00666 void CreateGestureCallback::fire(const LLUUID& inv_item)
00667 {
00668 if (inv_item.isNull())
00669 return;
00670
00671 gGestureManager.activateGesture(inv_item);
00672
00673 LLViewerInventoryItem* item = gInventory.getItem(inv_item);
00674 if (!item) return;
00675 gInventory.updateItem(item);
00676 gInventory.notifyObservers();
00677
00678 if(!LLPreview::show(inv_item,FALSE))
00679 {
00680 LLPreviewGesture* preview = LLPreviewGesture::show(LLString("Gesture: ") + item->getName(), inv_item, LLUUID::null);
00681
00682 gFloaterView->adjustToFitScreen(preview, FALSE);
00683 }
00684 }
00685
00686 LLInventoryCallbackManager gInventoryCallbacks;
00687
00688 void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
00689 const LLUUID& parent, const LLTransactionID& transaction_id,
00690 const std::string& name,
00691 const std::string& desc, LLAssetType::EType asset_type,
00692 LLInventoryType::EType inv_type, EWearableType wtype,
00693 U32 next_owner_perm,
00694 LLPointer<LLInventoryCallback> cb)
00695 {
00696 LLMessageSystem* msg = gMessageSystem;
00697 msg->newMessageFast(_PREHASH_CreateInventoryItem);
00698 msg->nextBlock(_PREHASH_AgentData);
00699 msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00700 msg->addUUIDFast(_PREHASH_SessionID, session_id);
00701 msg->nextBlock(_PREHASH_InventoryBlock);
00702 msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
00703 msg->addUUIDFast(_PREHASH_FolderID, parent);
00704 msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
00705 msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_perm);
00706 msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
00707 msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
00708 msg->addU8Fast(_PREHASH_WearableType, (U8)wtype);
00709 msg->addStringFast(_PREHASH_Name, name);
00710 msg->addStringFast(_PREHASH_Description, desc);
00711
00712 gAgent.sendReliableMessage();
00713 }
00714
00715 void copy_inventory_item(
00716 const LLUUID& agent_id,
00717 const LLUUID& current_owner,
00718 const LLUUID& item_id,
00719 const LLUUID& parent_id,
00720 const std::string& new_name,
00721 LLPointer<LLInventoryCallback> cb)
00722 {
00723 LLMessageSystem* msg = gMessageSystem;
00724 msg->newMessageFast(_PREHASH_CopyInventoryItem);
00725 msg->nextBlockFast(_PREHASH_AgentData);
00726 msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00727 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00728 msg->nextBlockFast(_PREHASH_InventoryData);
00729 msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
00730 msg->addUUIDFast(_PREHASH_OldAgentID, current_owner);
00731 msg->addUUIDFast(_PREHASH_OldItemID, item_id);
00732 msg->addUUIDFast(_PREHASH_NewFolderID, parent_id);
00733 msg->addStringFast(_PREHASH_NewName, new_name);
00734 gAgent.sendReliableMessage();
00735 }
00736
00737 void move_inventory_item(
00738 const LLUUID& agent_id,
00739 const LLUUID& session_id,
00740 const LLUUID& item_id,
00741 const LLUUID& parent_id,
00742 const std::string& new_name,
00743 LLPointer<LLInventoryCallback> cb)
00744 {
00745 LLMessageSystem* msg = gMessageSystem;
00746 msg->newMessageFast(_PREHASH_MoveInventoryItem);
00747 msg->nextBlockFast(_PREHASH_AgentData);
00748 msg->addUUIDFast(_PREHASH_AgentID, agent_id);
00749 msg->addUUIDFast(_PREHASH_SessionID, session_id);
00750 msg->addBOOLFast(_PREHASH_Stamp, FALSE);
00751 msg->nextBlockFast(_PREHASH_InventoryData);
00752 msg->addUUIDFast(_PREHASH_ItemID, item_id);
00753 msg->addUUIDFast(_PREHASH_FolderID, parent_id);
00754 msg->addStringFast(_PREHASH_NewName, new_name);
00755 gAgent.sendReliableMessage();
00756 }
00757
00758 class LLCopyInventoryFromNotecardResponder : public LLHTTPClient::Responder
00759 {
00760 public:
00761
00762 virtual void result(const LLSD& content)
00763 {
00764
00765 llinfos << "CopyInventoryFromNotecard request successful." << llendl;
00766 }
00767
00768
00769 virtual void error(U32 status, const std::string& reason)
00770 {
00771 llinfos << "LLCopyInventoryFromNotecardResponder::error "
00772 << status << ": " << reason << llendl;
00773 }
00774 };
00775
00776 void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src, U32 callback_id)
00777 {
00778 LLSD body;
00779 LLViewerRegion* viewer_region = NULL;
00780 if(object_id.notNull())
00781 {
00782 LLViewerObject* vo = gObjectList.findObject(object_id);
00783 if(vo)
00784 {
00785 viewer_region = vo->getRegion();
00786 }
00787 }
00788
00789
00790
00791 if(!viewer_region)
00792 {
00793 viewer_region = gAgent.getRegion();
00794 }
00795
00796 if(viewer_region)
00797 {
00798 std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
00799 if (!url.empty())
00800 {
00801 body["notecard-id"] = notecard_inv_id;
00802 body["object-id"] = object_id;
00803 body["item-id"] = src->getUUID();
00804 body["folder-id"] = gInventory.findCategoryUUIDForType(src->getType());
00805 body["callback-id"] = (LLSD::Integer)callback_id;
00806
00807 LLHTTPClient::post(url, body, new LLCopyInventoryFromNotecardResponder());
00808 }
00809 }
00810 }