summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerinventory.cpp
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llviewerinventory.cpp
Print done when done.
Diffstat (limited to 'indra/newview/llviewerinventory.cpp')
-rw-r--r--indra/newview/llviewerinventory.cpp705
1 files changed, 705 insertions, 0 deletions
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
new file mode 100644
index 0000000000..9c2638362e
--- /dev/null
+++ b/indra/newview/llviewerinventory.cpp
@@ -0,0 +1,705 @@
+/**
+ * @file llviewerinventory.cpp
+ * @brief Implementation of the viewer side inventory objects.
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llviewerinventory.h"
+
+#include "message.h"
+#include "indra_constants.h"
+
+#include "llagent.h"
+#include "llviewercontrol.h"
+#include "llconsole.h"
+#include "llinventorymodel.h"
+#include "llnotify.h"
+#include "llimview.h"
+#include "viewer.h"
+#include "llgesturemgr.h"
+
+#include "llinventoryview.h"
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+///----------------------------------------------------------------------------
+/// Class LLViewerInventoryItem
+///----------------------------------------------------------------------------
+
+LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ const LLPermissions& perm,
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ LLInventoryType::EType inv_type,
+ const LLString& name,
+ const LLString& desc,
+ const LLSaleInfo& sale_info,
+ U32 flags,
+ S32 creation_date_utc) :
+ LLInventoryItem(uuid, parent_uuid, perm, asset_uuid, type, inv_type,
+ name, desc, sale_info, flags, creation_date_utc),
+ mIsComplete(TRUE)
+{
+}
+
+LLViewerInventoryItem::LLViewerInventoryItem(const LLUUID& item_id,
+ const LLUUID& parent_id,
+ const char* name,
+ LLInventoryType::EType inv_type) :
+ LLInventoryItem(),
+ mIsComplete(FALSE)
+{
+ mUUID = item_id;
+ mParentUUID = parent_id;
+ mInventoryType = inv_type;
+ mName.assign(name);
+}
+
+LLViewerInventoryItem::LLViewerInventoryItem() :
+ LLInventoryItem(),
+ mIsComplete(FALSE)
+{
+}
+
+LLViewerInventoryItem::LLViewerInventoryItem(const LLViewerInventoryItem* other) :
+ LLInventoryItem()
+{
+ copy(other);
+ if (!mIsComplete)
+ {
+ llwarns << "LLViewerInventoryItem copy constructor for incomplete item"
+ << mUUID << llendl;
+ }
+}
+
+LLViewerInventoryItem::LLViewerInventoryItem(const LLInventoryItem *other) :
+ LLInventoryItem(other)
+{
+ LLInventoryItem::copy(other);
+ if (!mIsComplete)
+ {
+ llwarns << "LLViewerInventoryItem copy constructor for incomplete item"
+ << mUUID << llendl;
+ }
+}
+
+
+LLViewerInventoryItem::~LLViewerInventoryItem()
+{
+}
+
+// virtual
+void LLViewerInventoryItem::copy(const LLViewerInventoryItem* other)
+{
+ LLInventoryItem::copy(other);
+ mIsComplete = other->mIsComplete;
+ mTransactionID = other->mTransactionID;
+}
+
+void LLViewerInventoryItem::copy(const LLInventoryItem *other)
+{
+ LLInventoryItem::copy(other);
+ mIsComplete = true;
+ mTransactionID.setNull();
+}
+
+// virtual
+void LLViewerInventoryItem::clone(LLPointer<LLViewerInventoryItem>& newitem) const
+{
+ newitem = new LLViewerInventoryItem(this);
+ if(newitem.notNull())
+ {
+ LLUUID item_id;
+ item_id.generate();
+ newitem->setUUID(item_id);
+ }
+}
+
+void LLViewerInventoryItem::removeFromServer()
+{
+ llinfos << "Removing inventory item " << mUUID << " from server."
+ << llendl;
+
+ LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
+ gInventory.accountForUpdate(up);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RemoveInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_ItemID, mUUID);
+ gAgent.sendReliableMessage();
+}
+
+void LLViewerInventoryItem::updateServer(BOOL is_new) const
+{
+ if(!mIsComplete)
+ {
+ // *FIX: deal with this better.
+ // If we're crashing here then the UI is incorrectly enabled.
+ llerrs << "LLViewerInventoryItem::updateServer() - for incomplete item"
+ << llendl;
+ return;
+ }
+ if(gAgent.getID() != mPermissions.getOwner())
+ {
+ // *FIX: deal with this better.
+ llwarns << "LLViewerInventoryItem::updateServer() - for unowned item"
+ << llendl;
+ return;
+ }
+ LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
+ gInventory.accountForUpdate(up);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_UpdateInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addU32Fast(_PREHASH_CallbackID, 0);
+ packMessage(msg);
+ gAgent.sendReliableMessage();
+}
+
+void LLViewerInventoryItem::fetchFromServer(void) const
+{
+ if(!mIsComplete)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("FetchInventory");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("InventoryData");
+ msg->addUUID("OwnerID", mPermissions.getOwner());
+ msg->addUUID("ItemID", mUUID);
+ gAgent.sendReliableMessage();
+ }
+ else
+ {
+ // *FIX: this can be removed after a bit.
+ llwarns << "request to fetch complete item" << llendl;
+ }
+}
+
+// virtual
+BOOL LLViewerInventoryItem::unpackMessage(
+ LLMessageSystem* msg, const char* block, S32 block_num)
+{
+ BOOL rv = LLInventoryItem::unpackMessage(msg, block, block_num);
+ mIsComplete = TRUE;
+ return rv;
+}
+
+void LLViewerInventoryItem::setTransactionID(const LLTransactionID& transaction_id)
+{
+ mTransactionID = transaction_id;
+}
+// virtual
+void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const
+{
+ msg->addUUIDFast(_PREHASH_ItemID, mUUID);
+ msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
+ mPermissions.packMessage(msg);
+ msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
+ S8 type = static_cast<S8>(mType);
+ msg->addS8Fast(_PREHASH_Type, type);
+ type = static_cast<S8>(mInventoryType);
+ msg->addS8Fast(_PREHASH_InvType, type);
+ msg->addU32Fast(_PREHASH_Flags, mFlags);
+ mSaleInfo.packMessage(msg);
+ msg->addStringFast(_PREHASH_Name, mName);
+ msg->addStringFast(_PREHASH_Description, mDescription);
+ msg->addS32Fast(_PREHASH_CreationDate, mCreationDate);
+ U32 crc = getCRC32();
+ msg->addU32Fast(_PREHASH_CRC, crc);
+}
+// virtual
+BOOL LLViewerInventoryItem::importFile(FILE* fp)
+{
+ BOOL rv = LLInventoryItem::importFile(fp);
+ mIsComplete = TRUE;
+ return rv;
+}
+
+// virtual
+BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
+{
+ BOOL rv = LLInventoryItem::importLegacyStream(input_stream);
+ mIsComplete = TRUE;
+ return rv;
+}
+
+bool LLViewerInventoryItem::importFileLocal(FILE* fp)
+{
+ // TODO: convert all functions that return BOOL to return bool
+ bool rv = (LLInventoryItem::importFile(fp) ? true : false);
+ mIsComplete = false;
+ return rv;
+}
+
+bool LLViewerInventoryItem::exportFileLocal(FILE* fp) const
+{
+ char uuid_str[UUID_STR_LENGTH];
+ fprintf(fp, "\tinv_item\t0\n\t{\n");
+ mUUID.toString(uuid_str);
+ fprintf(fp, "\t\titem_id\t%s\n", uuid_str);
+ mParentUUID.toString(uuid_str);
+ fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
+ mPermissions.exportFile(fp);
+ fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
+ const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
+ if(inv_type_str) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str);
+ fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
+ fprintf(fp, "\t\tcreation_date\t%d\n", mCreationDate);
+ fprintf(fp,"\t}\n");
+ return true;
+}
+
+void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoveInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addBOOLFast(_PREHASH_Stamp, restamp);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_ItemID, mUUID);
+ msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
+ msg->addString("NewName", NULL);
+ gAgent.sendReliableMessage();
+}
+
+//void LLViewerInventoryItem::setCloneCount(S32 clones)
+//{
+// mClones = clones;
+//}
+
+//S32 LLViewerInventoryItem::getCloneCount() const
+//{
+// return mClones;
+//}
+
+///----------------------------------------------------------------------------
+/// Class LLViewerInventoryCategory
+///----------------------------------------------------------------------------
+
+LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ LLAssetType::EType pref,
+ const LLString& name,
+ const LLUUID& owner_id) :
+ LLInventoryCategory(uuid, parent_uuid, pref, name),
+ mOwnerID(owner_id),
+ mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
+ mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
+{
+ mDescendentsRequested.reset();
+}
+
+LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) :
+ mOwnerID(owner_id),
+ mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN),
+ mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
+{
+ mDescendentsRequested.reset();
+}
+
+LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other)
+{
+ copy(other);
+}
+
+LLViewerInventoryCategory::~LLViewerInventoryCategory()
+{
+}
+
+// virtual
+void LLViewerInventoryCategory::copy(const LLViewerInventoryCategory* other)
+{
+ LLInventoryCategory::copy(other);
+ mOwnerID = other->mOwnerID;
+ mVersion = other->mVersion;
+ mDescendentCount = other->mDescendentCount;
+ mDescendentsRequested = other->mDescendentsRequested;
+}
+
+
+void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoveInventoryFolder);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->addBOOL("Stamp", restamp);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_FolderID, mUUID);
+ msg->addUUIDFast(_PREHASH_ParentID, mParentUUID);
+ gAgent.sendReliableMessage();
+}
+
+void LLViewerInventoryCategory::updateServer(BOOL is_new) const
+{
+ // communicate that change with the server.
+ if(LLAssetType::AT_NONE != mPreferredType)
+ {
+ LLNotifyBox::showXml("CannotModifyProtectedCategories");
+ return;
+ }
+
+ LLInventoryModel::LLCategoryUpdate up(mParentUUID, is_new ? 1 : 0);
+ gInventory.accountForUpdate(up);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_FolderData);
+ packMessage(msg);
+ gAgent.sendReliableMessage();
+}
+
+void LLViewerInventoryCategory::removeFromServer( void )
+{
+ llinfos << "Removing inventory category " << mUUID << " from server."
+ << llendl;
+ // communicate that change with the server.
+ if(LLAssetType::AT_NONE != mPreferredType)
+ {
+ LLNotifyBox::showXml("CannotRemoveProtectedCategories");
+ return;
+ }
+
+ LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
+ gInventory.accountForUpdate(up);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RemoveInventoryFolder);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_FolderData);
+ msg->addUUIDFast(_PREHASH_FolderID, mUUID);
+ gAgent.sendReliableMessage();
+}
+
+bool LLViewerInventoryCategory::fetchDescendents()
+{
+ if((VERSION_UNKNOWN == mVersion)
+ && mDescendentsRequested.hasExpired())
+ {
+ const F32 FETCH_TIMER_EXPIRY = 10.0f;
+ mDescendentsRequested.reset();
+ mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY);
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("FetchInventoryDescendents");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("InventoryData");
+ msg->addUUID("FolderID", mUUID);
+ msg->addUUID("OwnerID", mOwnerID);
+ // bitfield
+ // 1 = by date
+ // 2 = folders by date
+ // Need to mask off anything but the first bit.
+ // This comes from LLInventoryFilter from llfolderview.h
+ U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
+ msg->addS32("SortOrder", sort_order);
+ msg->addBOOL("FetchFolders", FALSE);
+ msg->addBOOL("FetchItems", TRUE);
+ gAgent.sendReliableMessage();
+ return true;
+ }
+ return false;
+}
+
+bool LLViewerInventoryCategory::importFileLocal(FILE* fp)
+{
+ char buffer[MAX_STRING];
+ char keyword[MAX_STRING];
+ char valuestr[MAX_STRING];
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+ while(!feof(fp))
+ {
+ fgets(buffer, MAX_STRING, fp);
+ sscanf(buffer, " %s %s", keyword, valuestr);
+ if(!keyword)
+ {
+ continue;
+ }
+ if(0 == strcmp("{",keyword))
+ {
+ continue;
+ }
+ if(0 == strcmp("}", keyword))
+ {
+ break;
+ }
+ else if(0 == strcmp("cat_id", keyword))
+ {
+ mUUID.set(valuestr);
+ }
+ else if(0 == strcmp("parent_id", keyword))
+ {
+ mParentUUID.set(valuestr);
+ }
+ else if(0 == strcmp("type", keyword))
+ {
+ mType = LLAssetType::lookup(valuestr);
+ }
+ else if(0 == strcmp("pref_type", keyword))
+ {
+ mPreferredType = LLAssetType::lookup(valuestr);
+ }
+ else if(0 == strcmp("name", keyword))
+ {
+ //strcpy(valuestr, buffer + strlen(keyword) + 3);
+ // *NOTE: Not ANSI C, but widely supported.
+ sscanf(buffer, " %s %[^|]", keyword, valuestr);
+ mName.assign(valuestr);
+ LLString::replaceNonstandardASCII(mName, ' ');
+ LLString::replaceChar(mName, '|', ' ');
+ }
+ else if(0 == strcmp("owner_id", keyword))
+ {
+ mOwnerID.set(valuestr);
+ }
+ else if(0 == strcmp("version", keyword))
+ {
+ sscanf(valuestr, "%d", &mVersion);
+ }
+ else
+ {
+ llwarns << "unknown keyword '" << keyword
+ << "' in inventory import category " << mUUID << llendl;
+ }
+ }
+ return true;
+}
+
+bool LLViewerInventoryCategory::exportFileLocal(FILE* fp) const
+{
+ char uuid_str[UUID_STR_LENGTH];
+ fprintf(fp, "\tinv_category\t0\n\t{\n");
+ mUUID.toString(uuid_str);
+ fprintf(fp, "\t\tcat_id\t%s\n", uuid_str);
+ mParentUUID.toString(uuid_str);
+ fprintf(fp, "\t\tparent_id\t%s\n", uuid_str);
+ fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
+ fprintf(fp, "\t\tpref_type\t%s\n", LLAssetType::lookup(mPreferredType));
+ fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
+ mOwnerID.toString(uuid_str);
+ fprintf(fp, "\t\towner_id\t%s\n", uuid_str);
+ fprintf(fp, "\t\tversion\t%d\n", mVersion);
+ fprintf(fp,"\t}\n");
+ return true;
+}
+
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+
+/*
+void inventory_reliable_callback(void**, S32 status)
+{
+ if(0 != status)
+ {
+ char buffer[MAX_STRING];
+ sprintf(buffer, "Reliable packet failure: %d", status);
+ llwarns << buffer << llendl;
+ }
+}
+*/
+LLInventoryCallbackManager::LLInventoryCallbackManager() :
+ mLastCallback(0)
+{
+}
+
+LLInventoryCallbackManager::~LLInventoryCallbackManager()
+{
+}
+
+U32 LLInventoryCallbackManager::registerCB(LLPointer<LLInventoryCallback> cb)
+{
+ if (cb.isNull())
+ return 0;
+
+ mLastCallback++;
+ if (!mLastCallback)
+ mLastCallback++;
+
+ mMap[mLastCallback] = cb;
+ return mLastCallback;
+}
+
+void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
+{
+ if (!callback_id)
+ return;
+
+ std::map<U32, LLPointer<LLInventoryCallback> >::iterator i;
+
+ i = mMap.find(callback_id);
+ if (i != mMap.end())
+ {
+ (*i).second->fire(item_id);
+ mMap.erase(i);
+ }
+}
+
+void WearOnAvatarCallback::fire(const LLUUID& inv_item)
+{
+ if (inv_item.isNull())
+ return;
+
+ LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ wear_inventory_item_on_avatar(item);
+ }
+}
+
+RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
+{
+ mAttach = attachmentp;
+}
+RezAttachmentCallback::~RezAttachmentCallback()
+{
+}
+
+void RezAttachmentCallback::fire(const LLUUID& inv_item)
+{
+ if (inv_item.isNull())
+ return;
+
+ LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ rez_attachment(item, mAttach);
+ }
+}
+
+extern LLGestureManager gGestureManager;
+void ActivateGestureCallback::fire(const LLUUID& inv_item)
+{
+ if (inv_item.isNull())
+ return;
+
+ gGestureManager.activateGesture(inv_item);
+}
+
+LLInventoryCallbackManager gInventoryCallbacks;
+
+void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
+ const LLUUID& parent, const LLTransactionID& transaction_id,
+ const std::string& name,
+ const std::string& desc, LLAssetType::EType asset_type,
+ LLInventoryType::EType inv_type, EWearableType wtype,
+ U32 next_owner_perm,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_CreateInventoryItem);
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, agent_id);
+ msg->addUUIDFast(_PREHASH_SessionID, session_id);
+ msg->nextBlock(_PREHASH_InventoryBlock);
+ msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
+ msg->addUUIDFast(_PREHASH_FolderID, parent);
+ msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
+ msg->addU32Fast(_PREHASH_NextOwnerMask, next_owner_perm);
+ msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
+ msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
+ msg->addU8Fast(_PREHASH_WearableType, (U8)wtype);
+ msg->addStringFast(_PREHASH_Name, name);
+ msg->addStringFast(_PREHASH_Description, desc);
+
+ gAgent.sendReliableMessage();
+}
+
+void copy_inventory_item(
+ const LLUUID& agent_id,
+ const LLUUID& current_owner,
+ const LLUUID& item_id,
+ const LLUUID& parent_id,
+ const std::string& new_name,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_CopyInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, agent_id);
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb));
+ msg->addUUIDFast(_PREHASH_OldAgentID, current_owner);
+ msg->addUUIDFast(_PREHASH_OldItemID, item_id);
+ msg->addUUIDFast(_PREHASH_NewFolderID, parent_id);
+ msg->addString("NewName", new_name);
+ gAgent.sendReliableMessage();
+}
+
+void move_inventory_item(
+ const LLUUID& agent_id,
+ const LLUUID& session_id,
+ const LLUUID& item_id,
+ const LLUUID& parent_id,
+ const std::string& new_name,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_MoveInventoryItem);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, agent_id);
+ msg->addUUIDFast(_PREHASH_SessionID, session_id);
+ msg->addBOOLFast(_PREHASH_Stamp, false);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_ItemID, item_id);
+ msg->addUUIDFast(_PREHASH_FolderID, parent_id);
+ msg->addString("NewName", new_name);
+ gAgent.sendReliableMessage();
+}
+
+void _copy_inventory_from_notecard_hdr(const LLUUID& object_id, const LLUUID& notecard_inv_id)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_CopyInventoryFromNotecard);
+ msg->nextBlock(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlock(_PREHASH_NotecardData);
+ msg->addUUIDFast(_PREHASH_NotecardItemID, notecard_inv_id);
+ msg->addUUIDFast(_PREHASH_ObjectID, object_id);
+}
+
+void copy_inventory_from_notecard(const LLUUID& object_id, const LLUUID& notecard_inv_id, const LLInventoryItem *src)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ /*
+ * I was going to handle multiple inventory items here, but then I realized that
+ * we are only handling one at a time. Perhaps you can only select one at a
+ * time from the notecard?
+ */
+ _copy_inventory_from_notecard_hdr(object_id, notecard_inv_id);
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_ItemID, src->getUUID());
+ msg->addUUIDFast(_PREHASH_FolderID, gInventory.findCategoryUUIDForType(src->getType()));
+ gAgent.sendReliableMessage();
+}