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/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 +- 10 files changed, 458 insertions(+), 237 deletions(-) (limited to 'linden/indra') 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