From 78fb2791164591a3b7f853267370e85ee7857d4a Mon Sep 17 00:00:00 2001
From: unknown
Date: Mon, 29 Dec 2008 17:53:13 -0700
Subject: Added inventory changes for one method of inventory loss and upcoming
new inv capabilities
---
linden/etc/message.xml | 12 +
linden/indra/llcommon/indra_constants.h | 1 +
linden/indra/llinventory/llinventory.cpp | 43 ++-
linden/indra/llmessage/lliosocket.cpp | 3 +
linden/indra/llmessage/llpumpio.cpp | 18 +
linden/indra/llmessage/llpumpio.h | 9 +
linden/indra/newview/llinventorymodel.cpp | 533 ++++++++++++++++++-----------
linden/indra/newview/llinventorymodel.h | 38 +-
linden/indra/newview/llstartup.cpp | 3 +
linden/indra/newview/llviewerinventory.cpp | 41 ++-
linden/indra/newview/llviewerregion.cpp | 6 +-
11 files changed, 470 insertions(+), 237 deletions(-)
(limited to 'linden')
diff --git a/linden/etc/message.xml b/linden/etc/message.xml
index 80dc560..0695d05 100644
--- a/linden/etc/message.xml
+++ b/linden/etc/message.xml
@@ -564,6 +564,18 @@
true
FetchInventoryDescendents
+ false
+
+ WebFetchInventoryDescendents
+ true
+
+ FetchInventory
+ true
+
+ FetchLibDescendents
+ true
+
+ FetchLib
true
diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h
index 1c48a5c..fcb2aaf 100644
--- a/linden/indra/llcommon/indra_constants.h
+++ b/linden/indra/llcommon/indra_constants.h
@@ -251,6 +251,7 @@ const U8 GOD_NOT = 0;
const LLUUID LL_UUID_ALL_AGENTS("44e87126-e794-4ded-05b3-7c42da3d5cdb");
// Governor Linden's agent id.
+const LLUUID ALEXANDRIA_LINDEN_ID("ba2a564a-f0f1-4b82-9c61-b7520bfcd09f");
const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
// Maintenance's group id.
diff --git a/linden/indra/llinventory/llinventory.cpp b/linden/indra/llinventory/llinventory.cpp
index 457a0cb..0c7e0ed 100644
--- a/linden/indra/llinventory/llinventory.cpp
+++ b/linden/indra/llinventory/llinventory.cpp
@@ -60,6 +60,9 @@ static const std::string INV_SALE_INFO_LABEL("sale_info");
static const std::string INV_FLAGS_LABEL("flags");
static const std::string INV_CREATION_DATE_LABEL("created_at");
+// key used by agent-inventory-service
+static const std::string INV_ASSET_TYPE_LABEL_WS("type_default");
+static const std::string INV_FOLDER_ID_LABEL_WS("category_id");
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
@@ -949,11 +952,13 @@ LLSD LLInventoryItem::asLLSD() const
sd[INV_SHADOW_ID_LABEL] = shadow_id;
}
sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
+ sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
if(inv_type_str)
{
sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
}
+ //sd[INV_FLAGS_LABEL] = (S32)mFlags;
sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
sd[INV_SALE_INFO_LABEL] = mSaleInfo;
sd[INV_NAME_LABEL] = mName;
@@ -1026,17 +1031,40 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)
w = INV_ASSET_TYPE_LABEL;
if (sd.has(w))
{
- mType = LLAssetType::lookup(sd[w].asString());
+ if (sd[w].isString())
+ {
+ mType = LLAssetType::lookup(sd[w].asString().c_str());
+ }
+ else if (sd[w].isInteger())
+ {
+ S8 type = (U8)sd[w].asInteger();
+ mType = static_cast(type);
+ }
}
w = INV_INVENTORY_TYPE_LABEL;
if (sd.has(w))
{
- mInventoryType = LLInventoryType::lookup(sd[w].asString());
+ if (sd[w].isString())
+ {
+ mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());
+ }
+ else if (sd[w].isInteger())
+ {
+ S8 type = (U8)sd[w].asInteger();
+ mInventoryType = static_cast(type);
+ }
}
w = INV_FLAGS_LABEL;
if (sd.has(w))
{
- mFlags = ll_U32_from_sd(sd[w]);
+ if (sd[w].isBinary())
+ {
+ mFlags = ll_U32_from_sd(sd[w]);
+ }
+ else if(sd[w].isInteger())
+ {
+ mFlags = sd[w].asInteger();
+ }
}
w = INV_NAME_LABEL;
if (sd.has(w))
@@ -1394,7 +1422,7 @@ bool LLInventoryCategory::fromLLSD(LLSD& sd)
{
std::string w;
- w = INV_ITEM_ID_LABEL;
+ w = INV_FOLDER_ID_LABEL_WS;
if (sd.has(w))
{
mUUID = sd[w];
@@ -1410,6 +1438,13 @@ bool LLInventoryCategory::fromLLSD(LLSD& sd)
S8 type = (U8)sd[w].asInteger();
mPreferredType = static_cast(type);
}
+ w = INV_ASSET_TYPE_LABEL_WS;
+ if (sd.has(w))
+ {
+ S8 type = (U8)sd[w].asInteger();
+ mPreferredType = static_cast(type);
+ }
+
w = INV_NAME_LABEL;
if (sd.has(w))
{
diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp
index dec83b0..28fee37 100644
--- a/linden/indra/llmessage/lliosocket.cpp
+++ b/linden/indra/llmessage/lliosocket.cpp
@@ -355,8 +355,11 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl(
}
else if(APR_STATUS_IS_EAGAIN(status))
{
+/*Commented out by Aura 9-9-8 for DEV-19961.
// everything is fine, but we can terminate this process pump.
+
rv = STATUS_BREAK;
+*/
}
else
{
diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp
index c92612f..6adf9c2 100644
--- a/linden/indra/llmessage/llpumpio.cpp
+++ b/linden/indra/llmessage/llpumpio.cpp
@@ -269,6 +269,13 @@ bool LLPumpIO::setTimeoutSeconds(F32 timeout)
return true;
}
+void LLPumpIO::adjustTimeoutSeconds(F32 delta)
+{
+ // If no chain is running, bail
+ if(current_chain_t() == mCurrentChain) return;
+ (*mCurrentChain).adjustTimeoutSeconds(delta);
+}
+
static std::string events_2_string(apr_int16_t events)
{
std::ostringstream ostr;
@@ -1161,3 +1168,14 @@ void LLPumpIO::LLChainInfo::setTimeoutSeconds(F32 timeout)
mTimer.stop();
}
}
+
+void LLPumpIO::LLChainInfo::adjustTimeoutSeconds(F32 delta)
+{
+ LLMemType m1(LLMemType::MTYPE_IO_PUMP);
+ if(mTimer.getStarted())
+ {
+ F64 expiry = mTimer.expiresAt();
+ expiry += delta;
+ mTimer.setExpiryAt(expiry);
+ }
+}
diff --git a/linden/indra/llmessage/llpumpio.h b/linden/indra/llmessage/llpumpio.h
index d2392a3..daff723 100644
--- a/linden/indra/llmessage/llpumpio.h
+++ b/linden/indra/llmessage/llpumpio.h
@@ -166,6 +166,14 @@ public:
bool setTimeoutSeconds(F32 timeout);
/**
+ * @brief Adjust the timeout of the running chain.
+ *
+ * This method has no effect if there is no timeout on the chain.
+ * @param delta The number of seconds to add to/remove from the timeout.
+ */
+ void adjustTimeoutSeconds(F32 delta);
+
+ /**
* @brief Set up file descriptors for for the running chain.
* @see rebuildPollset()
*
@@ -349,6 +357,7 @@ protected:
// methods
LLChainInfo();
void setTimeoutSeconds(F32 timeout);
+ void adjustTimeoutSeconds(F32 delta);
// basic member data
bool mInit;
diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp
index b1e3017..73f0fb3 100644
--- a/linden/indra/newview/llinventorymodel.cpp
+++ b/linden/indra/newview/llinventorymodel.cpp
@@ -73,7 +73,6 @@ F32 LLInventoryModel::sMinTimeBetweenFetches = 0.3f;
F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f;
BOOL LLInventoryModel::sTimelyFetchPending = FALSE;
LLFrameTimer LLInventoryModel::sFetchTimer;
-LLInventoryModel::cat_map_t LLInventoryModel::sBulkFetchMap;
S16 LLInventoryModel::sBulkFetchCount = 0;
// RN: for some reason, using std::queue in the header file confuses the compiler which things it's an xmlrpc_queue
@@ -85,7 +84,7 @@ static std::deque sFetchQueue;
//BOOL decompress_file(const char* src_filename, const char* dst_filename);
const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
-const S32 MAX_FETCH_RETRIES = 5;
+const S32 MAX_FETCH_RETRIES = 10;
const char CACHE_FORMAT_STRING[] = "%s.inv";
const char* NEW_CATEGORY_NAME = "New Folder";
const char* NEW_CATEGORY_NAMES[LLAssetType::AT_COUNT] =
@@ -990,13 +989,24 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer)
// Call this method when it's time to update everyone on a new state,
// by default, the inventory model will not update observers
// automatically.
-void LLInventoryModel::notifyObservers()
+// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
+void LLInventoryModel::notifyObservers(const std::string service_name)
{
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
{
LLInventoryObserver* observer = *iter;
- observer->changed(mModifyMask);
+
+ if (service_name.empty())
+ {
+ observer->changed(mModifyMask);
+ }
+ else
+ {
+ observer->mMessageName = service_name;
+ observer->changed(mModifyMask);
+ }
+
// safe way to incrament since changed may delete entries! (@!##%@!@&*!)
iter = mObservers.upper_bound(observer);
}
@@ -1038,6 +1048,79 @@ void LLInventoryModel::mock(const LLUUID& root_id)
}
*/
+//If we get back a normal response, handle it here
+void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
+{
+ start_new_inventory_observer();
+
+ /*LLUUID agent_id;
+ agent_id = content["agent_id"].asUUID();
+ if(agent_id != gAgent.getID())
+ {
+ llwarns << "Got a inventory update for the wrong agent: " << agent_id
+ << llendl;
+ return;
+ }*/
+ item_array_t items;
+ update_map_t update;
+ S32 count = content["items"].size();
+ bool all_one_folder = true;
+ LLUUID folder_id;
+ // Does this loop ever execute more than once? -Gigs
+ for(S32 i = 0; i < count; ++i)
+ {
+ LLPointer titem = new LLViewerInventoryItem;
+ titem->unpackMessage(content["items"][i]);
+
+ lldebugs << "LLInventoryModel::messageUpdateCore() item id:"
+ << titem->getUUID() << llendl;
+ items.push_back(titem);
+ // examine update for changes.
+ LLViewerInventoryItem* itemp = gInventory.getItem(titem->getUUID());
+ if(itemp)
+ {
+ if(titem->getParentUUID() == itemp->getParentUUID())
+ {
+ update[titem->getParentUUID()];
+ }
+ else
+ {
+ ++update[titem->getParentUUID()];
+ --update[itemp->getParentUUID()];
+ }
+ }
+ else
+ {
+ ++update[titem->getParentUUID()];
+ }
+ if (folder_id.isNull())
+ {
+ folder_id = titem->getParentUUID();
+ }
+ else
+ {
+ all_one_folder = false;
+ }
+ }
+
+ U32 changes = 0x0;
+ //as above, this loop never seems to loop more than once per call
+ for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ changes |= gInventory.updateItem(*it);
+ }
+ gInventory.notifyObservers("fetchinventory");
+ gViewerWindow->getWindow()->decBusyCount();
+}
+
+//If we get back an error (not found, etc...), handle it here
+void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason)
+{
+ llinfos << "fetchInventory::error "
+ << status << ": " << reason << llendl;
+ gInventory.notifyObservers("fetchinventory");
+}
+
void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
{
LLViewerInventoryCategory* cat = getCategory(folder_id);
@@ -1065,21 +1148,31 @@ void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
}
//Initialize statics.
-LLAlertDialog* LLInventoryModel::fetchDescendentsResponder::sRetryDialog=NULL;
-LLSD LLInventoryModel::fetchDescendentsResponder::sRetrySD;
-
bool LLInventoryModel::isBulkFetchProcessingComplete()
{
return ( (sFetchQueue.empty()
- && sBulkFetchMap.empty()
- && sBulkFetchCount==0) ? TRUE : FALSE ) ;
+ && sBulkFetchCount<=0) ? TRUE : FALSE ) ;
}
+class fetchDescendentsResponder: public LLHTTPClient::Responder
+{
+ public:
+ fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
+ //fetchDescendentsResponder() {};
+ void result(const LLSD& content);
+ void error(U32 status, const std::string& reason);
+ public:
+ typedef std::vector folder_ref_t;
+ protected:
+ LLSD mRequestSD;
+};
+
//If we get back a normal response, handle it here
-void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
-{
+void fetchDescendentsResponder::result(const LLSD& content)
+{
if (content.has("folders"))
{
+
for(LLSD::array_const_iterator folder_it = content["folders"].beginArray();
folder_it != content["folders"].endArray();
++folder_it)
@@ -1087,19 +1180,54 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
LLSD folder_sd = *folder_it;
- LLUUID agent_id = folder_sd["agent-id"];
+ //LLUUID agent_id = folder_sd["agent_id"];
- if(agent_id != gAgent.getID()) //This should never happen.
- {
- llwarns << "Got a UpdateInventoryItem for the wrong agent."
- << llendl;
- break;
- }
- LLUUID parent_id = folder_sd["folder-id"];
- LLUUID owner_id = folder_sd["owner-id"];
+ //if(agent_id != gAgent.getID()) //This should never happen.
+ //{
+ // llwarns << "Got a UpdateInventoryItem for the wrong agent."
+ // << llendl;
+ // break;
+ //}
+
+ LLUUID parent_id = folder_sd["folder_id"];
+ LLUUID owner_id = folder_sd["owner_id"];
S32 version = (S32)folder_sd["version"].asInteger();
S32 descendents = (S32)folder_sd["descendents"].asInteger();
LLPointer tcategory = new LLViewerInventoryCategory(owner_id);
+
+ if (parent_id.isNull())
+ {
+ LLPointer titem = new LLViewerInventoryItem;
+ for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
+ item_it != folder_sd["items"].endArray();
+ ++item_it)
+ {
+ LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
+ if (lost_uuid.notNull())
+ {
+ LLSD item = *item_it;
+ titem->unpackMessage(item);
+
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ titem->setParent(lost_uuid);
+ titem->updateParentOnServer(FALSE);
+ gInventory.updateItem(titem);
+ gInventory.notifyObservers("fetchDescendents");
+
+ }
+ }
+ }
+
+ LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id);
+ if (!pcat)
+ {
+ continue;
+ }
+
for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray();
category_it != folder_sd["categories"].endArray();
++category_it)
@@ -1107,7 +1235,7 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
LLSD category = *category_it;
tcategory->fromLLSD(category);
- if (sFullFetchStarted)
+ if (LLInventoryModel::sFullFetchStarted)
{
sFetchQueue.push_back(tcategory->getUUID());
}
@@ -1139,37 +1267,37 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
}
}
- if (content.has("bad-folders"))
+ if (content.has("bad_folders"))
{
- for(LLSD::array_const_iterator folder_it = content["bad-folders"].beginArray();
- folder_it != content["bad-folders"].endArray();
+ for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray();
+ folder_it != content["bad_folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
//These folders failed on the dataserver. We probably don't want to retry them.
- llinfos << "Folder " << folder_sd["folder-id"].asString()
+ llinfos << "Folder " << folder_sd["folder_id"].asString()
<< "Error: " << folder_sd["error"].asString() << llendl;
}
}
LLInventoryModel::incrBulkFetch(-1);
- if (isBulkFetchProcessingComplete())
+ if (LLInventoryModel::isBulkFetchProcessingComplete())
{
llinfos << "Inventory fetch completed" << llendl;
- if (sFullFetchStarted)
+ if (LLInventoryModel::sFullFetchStarted)
{
- sAllFoldersFetched = TRUE;
+ LLInventoryModel::sAllFoldersFetched = TRUE;
}
- stopBackgroundFetch();
+ LLInventoryModel::stopBackgroundFetch();
}
- gInventory.notifyObservers();
+ gInventory.notifyObservers("fetchDescendents");
}
//If we get back an error (not found, etc...), handle it here
-void LLInventoryModel::fetchDescendentsResponder::error(U32 status, const std::string& reason)
+void fetchDescendentsResponder::error(U32 status, const std::string& reason)
{
llinfos << "fetchDescendentsResponder::error "
<< status << ": " << reason << llendl;
@@ -1183,61 +1311,22 @@ void LLInventoryModel::fetchDescendentsResponder::error(U32 status, const std::s
++folder_it)
{
LLSD folder_sd = *folder_it;
- sRetrySD["folders"].append(folder_sd);
- }
- sMinTimeBetweenFetches = 10.0f; //Add 10 seconds for every time out in this sequence.
-
- if (!sRetryDialog) //The dialog isn't up. Prompt the resident.
- {
- sRetryDialog = gViewerWindow->alertXml("RetryFetchInventoryDescendents", onClickRetry, this);
+ LLUUID folder_id = folder_sd["folder_id"];
+ sFetchQueue.push_front(folder_id);
}
}
else
{
- if (isBulkFetchProcessingComplete())
+ if (LLInventoryModel::isBulkFetchProcessingComplete())
{
- if (sFullFetchStarted)
+ if (LLInventoryModel::sFullFetchStarted)
{
- sAllFoldersFetched = TRUE;
+ LLInventoryModel::sAllFoldersFetched = TRUE;
}
- stopBackgroundFetch();
+ LLInventoryModel::stopBackgroundFetch();
}
}
- gInventory.notifyObservers();
-}
-
-void LLInventoryModel::fetchDescendentsResponder::onClickRetry(S32 option, void* userdata)
-{
- if (option == 0)
- {
- std::string url;
-
- LLViewerRegion * agent_region = gAgent.getRegion();
- if (agent_region)
- {
- url = agent_region->getCapability("FetchInventoryDescendents");
- }
-
- if (!url.empty()) //Capability found. Build up LLSD and use it.
- {
- LLSD body = sRetrySD;
- LLInventoryModel::incrBulkFetch(1);
- LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body),300);
- }
- }
- else
- {
- if (isBulkFetchProcessingComplete())
- {
- if (sFullFetchStarted)
- {
- sAllFoldersFetched = TRUE;
- }
- stopBackgroundFetch();
- }
- }
- sRetryDialog=NULL;
- sRetrySD.clear();
+ gInventory.notifyObservers("fetchDescendents");
}
//static Bundle up a bunch of requests to send all at once.
@@ -1250,7 +1339,7 @@ void LLInventoryModel::bulkFetch(std::string url)
S16 max_concurrent_fetches=8;
F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely.
- if (sMinTimeBetweenFetches <= new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above.
+ if (sMinTimeBetweenFetches < new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above.
if(gDisconnected
|| sBulkFetchCount > max_concurrent_fetches
@@ -1263,84 +1352,83 @@ void LLInventoryModel::bulkFetch(std::string url)
//redundant requests. When we get rid of the old code entirely, we can change
//the dequeue to a map. In the new model, there is no benefit to queue order.
U32 folder_count=0;
- U32 max_batch_size=10;
- while( !(sFetchQueue.empty() ) )
- {
- LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front());
-
- if (cat)
- {
- if ( !gInventory.isCategoryComplete(cat->getUUID()) ) //grab this folder.
- {
- sBulkFetchMap[(cat->getUUID())] = cat;
- }
- else if (sFullFetchStarted)
- { //Already have this folder but append child folders to list.
- // add all children to queue
- parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID());
- if (cat_it != gInventory.mParentChildCategoryTree.end())
- {
- cat_array_t* child_categories = cat_it->second;
-
- for (S32 child_num = 0; child_num < child_categories->count(); child_num++)
- {
- sFetchQueue.push_back(child_categories->get(child_num)->getUUID());
- }
- }
+ U32 max_batch_size=5;
+
+ U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
+
+ LLSD body;
+ LLSD body_lib;
+ while( !(sFetchQueue.empty() ) && (folder_count < max_batch_size) )
+ {
+ if (sFetchQueue.front().isNull()) //DEV-17797
+ {
+ LLSD folder_sd;
+ folder_sd["folder_id"] = LLUUID::null.asString();
+ folder_sd["owner_id"] = gAgent.getID();
+ folder_sd["sort_order"] = (LLSD::Integer)sort_order;
+ folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE;
+ folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
+ body["folders"].append(folder_sd);
+ folder_count++;
+ }
+ else
+ {
+
- }
- }
+ LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front());
+
+ if (cat)
+ {
+ if ( LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion())
+ {
+ LLSD folder_sd;
+ folder_sd["folder_id"] = cat->getUUID();
+ folder_sd["owner_id"] = cat->getOwnerID();
+ folder_sd["sort_order"] = (LLSD::Integer)sort_order;
+ folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted;
+ folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
+
+ if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID())
+ body_lib["folders"].append(folder_sd);
+ else
+ body["folders"].append(folder_sd);
+ folder_count++;
+ }
+ if (sFullFetchStarted)
+ { //Already have this folder but append child folders to list.
+ // add all children to queue
+ parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID());
+ if (cat_it != gInventory.mParentChildCategoryTree.end())
+ {
+ cat_array_t* child_categories = cat_it->second;
+
+ for (S32 child_num = 0; child_num < child_categories->count(); child_num++)
+ {
+ sFetchQueue.push_back(child_categories->get(child_num)->getUUID());
+ }
+ }
+
+ }
+ }
+ }
sFetchQueue.pop_front();
}
-
- if (!sBulkFetchMap.empty()) //There's stuff to fetch.
- {
- U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
-
- LLSD body;
-
- cat_map_t::iterator iter=sBulkFetchMap.begin();
- while( iter!=sBulkFetchMap.end() && (folder_count < max_batch_size) )
- {
- LLViewerInventoryCategory* cat = iter->second;
-
- if (cat && !gInventory.isCategoryComplete(cat->getUUID()) ) //Category exists
- {
- BOOL fetchItems=TRUE;
- if ( sFullFetchStarted
- && gInventory.isCategoryComplete(cat->getUUID()) )
- {
- fetchItems=FALSE;
- }
-
- LLSD folder_sd;
- folder_sd["folder-id"] = cat->getUUID();
- folder_sd["owner-id"] = cat->getOwnerID();
- folder_sd["sort-order"] = (LLSD::Integer)sort_order;
- folder_sd["fetch-folders"] = (LLSD::Boolean)sFullFetchStarted;
- folder_sd["fetch-items"] = (LLSD::Boolean)fetchItems;
- body["folders"].append(folder_sd);
-
- folder_count++;
- }
- sBulkFetchMap.erase(iter);
- iter=sBulkFetchMap.begin();
- }
-
- if (iter == sBulkFetchMap.end()) sBulkFetchMap.clear();
-
if (folder_count > 0)
{
sBulkFetchCount++;
-
- LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body));
+ if (body["folders"].size())
+ {
+ LLHTTPClient::post(url, body, new fetchDescendentsResponder(body),300.0);
+ }
+ if (body_lib["folders"].size())
+ {
+ std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents");
+ LLHTTPClient::post(url_lib, body_lib, new fetchDescendentsResponder(body_lib),300.0);
+ }
sFetchTimer.reset();
}
-
- }
-
- if (isBulkFetchProcessingComplete())
+ else if (isBulkFetchProcessingComplete())
{
if (sFullFetchStarted)
{
@@ -1391,6 +1479,14 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
}
//static
+void LLInventoryModel::findLostItems()
+{
+ sBackgroundFetchActive = TRUE;
+ sFetchQueue.push_back(LLUUID::null);
+ gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
+}
+
+//static
void LLInventoryModel::stopBackgroundFetch()
{
if (sBackgroundFetchActive)
@@ -1409,14 +1505,7 @@ void LLInventoryModel::backgroundFetch(void*)
if (sBackgroundFetchActive)
{
//If we'll be using the capability, we'll be sending batches and the background thing isn't as important.
- std::string url;
-
- LLViewerRegion * agent_region = gAgent.getRegion();
- if (agent_region)
- {
- url = agent_region->getCapability("FetchInventoryDescendents");
- }
-
+ std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
if (!url.empty())
{
bulkFetch(url);
@@ -3373,12 +3462,72 @@ bool LLInventoryFetchObserver::isEverythingComplete() const
return mIncomplete.empty();
}
+void fetch_items_from_llsd(const LLSD& items_llsd)
+{
+ if (!items_llsd.size()) return;
+ LLSD body;
+ body[0]["cap_name"] = "FetchInventory";
+ body[1]["cap_name"] = "FetchLib";
+ for (S32 i=0; i= body[i].size()) continue;
+ std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
+
+ if (!url.empty())
+ {
+ body[i]["agent_id"] = gAgent.getID();
+ LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
+ break;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ BOOL start_new_message = TRUE;
+ for (S32 j=0; jnewMessageFast(_PREHASH_FetchInventory);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ }
+ msg->nextBlockFast(_PREHASH_InventoryData);
+ msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
+ msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
+ if(msg->isSendFull(NULL))
+ {
+ start_new_message = TRUE;
+ gAgent.sendReliableMessage();
+ }
+ }
+ if(!start_new_message)
+ {
+ gAgent.sendReliableMessage();
+ }
+ }
+}
+
void LLInventoryFetchObserver::fetchItems(
const LLInventoryFetchObserver::item_ref_t& ids)
{
- LLMessageSystem* msg = gMessageSystem;
- BOOL start_new_message = TRUE;
LLUUID owner_id;
+ LLSD items_llsd;
for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
{
LLViewerInventoryItem* item = gInventory.getItem(*it);
@@ -3400,31 +3549,18 @@ void LLInventoryFetchObserver::fetchItems(
// assume it's agent inventory.
owner_id = gAgent.getID();
}
-
+
// It's incomplete, so put it on the incomplete container, and
// pack this on the message.
mIncomplete.push_back(*it);
- if(start_new_message)
- {
- start_new_message = FALSE;
- msg->newMessageFast(_PREHASH_FetchInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addUUIDFast(_PREHASH_OwnerID, owner_id);
- msg->addUUIDFast(_PREHASH_ItemID, (*it));
- if(msg->isSendFull(NULL))
- {
- start_new_message = TRUE;
- gAgent.sendReliableMessage();
- }
- }
- if(!start_new_message)
- {
- gAgent.sendReliableMessage();
+
+ // Prepare the data to fetch
+ LLSD item_entry;
+ item_entry["owner_id"] = owner_id;
+ item_entry["item_id"] = (*it);
+ items_llsd.append(item_entry);
}
+ fetch_items_from_llsd(items_llsd);
}
// virtual
@@ -3579,9 +3715,8 @@ void LLInventoryFetchComboObserver::fetch(
// descendent of an incomplete folder because the item will show
// up in an inventory descendents message soon enough so we do not
// have to fetch it individually.
+ LLSD items_llsd;
LLUUID owner_id;
- LLMessageSystem* msg = gMessageSystem;
- bool start_new_message = true;
for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
{
LLViewerInventoryItem* item = gInventory.getItem(*iit);
@@ -3604,33 +3739,17 @@ void LLInventoryFetchComboObserver::fetch(
}
if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
{
- lldebugs << "fetching item " << *iit << llendl;
- if(start_new_message)
- {
- start_new_message = false;
- msg->newMessageFast(_PREHASH_FetchInventory);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- msg->nextBlockFast(_PREHASH_InventoryData);
- msg->addUUIDFast(_PREHASH_OwnerID, owner_id);
- msg->addUUIDFast(_PREHASH_ItemID, (*iit));
- if(msg->isSendFullFast(_PREHASH_InventoryData))
- {
- start_new_message = true;
- gAgent.sendReliableMessage();
- }
+ LLSD item_entry;
+ item_entry["owner_id"] = owner_id;
+ item_entry["item_id"] = (*iit);
+ items_llsd.append(item_entry);
}
else
{
lldebugs << "not worrying about " << *iit << llendl;
}
}
- if(!start_new_message)
- {
- gAgent.sendReliableMessage();
- }
+ fetch_items_from_llsd(items_llsd);
}
void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
@@ -3676,7 +3795,17 @@ void LLInventoryAddedObserver::changed(U32 mask)
// the network, figure out which item was updated.
// Code from Gigs Taggert, sin allowed by JC.
LLMessageSystem* msg = gMessageSystem;
- std::string msg_name = msg->getMessageName();
+
+ std::string msg_name;
+ if (mMessageName.empty())
+ {
+ msg_name = msg->getMessageName();
+ }
+ else
+ {
+ msg_name = mMessageName;
+ }
+
if (msg_name.empty())
{
return;
diff --git a/linden/indra/newview/llinventorymodel.h b/linden/indra/newview/llinventorymodel.h
index 8017410..d2be761 100644
--- a/linden/indra/newview/llinventorymodel.h
+++ b/linden/indra/newview/llinventorymodel.h
@@ -69,6 +69,7 @@ public:
};
virtual ~LLInventoryObserver() {};
virtual void changed(U32 mask) = 0;
+ std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -110,20 +111,17 @@ public:
LLInventoryModel();
~LLInventoryModel();
- class fetchDescendentsResponder: public LLHTTPClient::Responder
+ class fetchInventoryResponder: public LLHTTPClient::Responder
{
- public:
- fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
- void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
- static void onClickRetry(S32 option, void* userdata);
- static void appendRetryList(LLSD retry_sd);
- public:
- typedef std::vector folder_ref_t;
- protected:
- LLSD mRequestSD;
- static LLSD sRetrySD;
- static LLAlertDialog *sRetryDialog;
+ public:
+ fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
+ void result(const LLSD& content);
+ void error(U32 status, const std::string& reason);
+
+ public:
+ typedef std::vector folder_ref_t;
+ protected:
+ LLSD mRequestSD;
};
//
@@ -268,7 +266,8 @@ public:
// Call this method when it's time to update everyone on a new
// state, by default, the inventory model will not update
// observers automatically.
- void notifyObservers();
+ // The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
+ void notifyObservers(const std::string service_name="");
// This allows outsiders to tell the inventory if something has
// been changed 'under the hood', but outside the control of the
@@ -370,7 +369,7 @@ public:
// start and stop background breadth-first fetching of inventory contents
// this gets triggered when performing a filter-search
static void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null); // start fetch process
- static void stopBackgroundFetch(); // stop fetch process
+ static void findLostItems();
static BOOL backgroundFetchActive();
static bool isEverythingFetched();
static void backgroundFetch(void*); // background fetch idle function
@@ -419,7 +418,6 @@ protected:
static void processInventoryDescendents(LLMessageSystem* msg, void**);
static void processMoveInventoryItem(LLMessageSystem* msg, void**);
static void processFetchInventoryReply(LLMessageSystem* msg, void**);
- static bool isBulkFetchProcessingComplete();
bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting);
@@ -460,11 +458,8 @@ protected:
observer_list_t mObservers;
// completing the fetch once per session should be sufficient
- static cat_map_t sBulkFetchMap;
static BOOL sBackgroundFetchActive;
static BOOL sTimelyFetchPending;
- static BOOL sAllFoldersFetched;
- static BOOL sFullFetchStarted;
static S32 sNumFetchRetries;
static LLFrameTimer sFetchTimer;
static F32 sMinTimeBetweenFetches;
@@ -477,6 +472,11 @@ protected:
public:
// *NOTE: DEBUG functionality
void dumpInventory();
+ static bool isBulkFetchProcessingComplete();
+ static void stopBackgroundFetch(); // stop fetch process
+
+ static BOOL sFullFetchStarted;
+ static BOOL sAllFoldersFetched;
};
// a special inventory model for the agent
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 6371f2b..05ecf87 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -2251,6 +2251,9 @@ bool idle_startup()
}
}
+ //DEV-17797. get null folder. Any items found here moved to Lost and Found
+ LLInventoryModel::findLostItems();
+
LLStartUp::setStartupState( STATE_PRECACHE );
timeout.reset();
return FALSE;
diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp
index 6d9d685..0323bb7 100644
--- a/linden/indra/newview/llviewerinventory.cpp
+++ b/linden/indra/newview/llviewerinventory.cpp
@@ -196,15 +196,34 @@ 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();
+ std::string url;
+
+ if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
+ url = gAgent.getRegion()->getCapability("FetchLib");
+ else
+ url = gAgent.getRegion()->getCapability("FetchInventory");
+
+ if (!url.empty())
+ {
+ LLSD body;
+ body["agent_id"] = gAgent.getID();
+ body["items"][0]["owner_id"] = mPermissions.getOwner();
+ body["items"][0]["item_id"] = mUUID;
+
+ LLHTTPClient::post(url, body, new LLInventoryModel::fetchInventoryResponder(body));
+ }
+ else
+ {
+ 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
{
@@ -441,7 +460,7 @@ bool LLViewerInventoryCategory::fetchDescendents()
// This comes from LLInventoryFilter from llfolderview.h
U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
- std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents");
+ std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
if (!url.empty()) //Capability found. Build up LLSD and use it.
{
@@ -449,7 +468,7 @@ bool LLViewerInventoryCategory::fetchDescendents()
}
else
{ //Deprecated, but if we don't have a capability, use the old system.
- llinfos << "FetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl;
+ llinfos << "WebFetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("FetchInventoryDescendents");
msg->nextBlock("AgentData");
diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp
index 2944d9d..b2fd621 100644
--- a/linden/indra/newview/llviewerregion.cpp
+++ b/linden/indra/newview/llviewerregion.cpp
@@ -1391,8 +1391,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("DispatchRegionInfo");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("FetchInventoryDescendents");
+ capabilityNames.append("FetchInventory");
+ capabilityNames.append("WebFetchInventoryDescendents");
+ capabilityNames.append("FetchLib");
+ capabilityNames.append("FetchLibDescendents");
capabilityNames.append("GroupProposalBallot");
+ capabilityNames.append("HomeLocation");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("NewFileAgentInventory");
--
cgit v1.1