aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt25
-rw-r--r--linden/etc/message.xml12
-rw-r--r--linden/indra/llcommon/indra_constants.h1
-rw-r--r--linden/indra/llinventory/llinventory.cpp43
-rw-r--r--linden/indra/llmessage/lliosocket.cpp3
-rw-r--r--linden/indra/llmessage/llpumpio.cpp18
-rw-r--r--linden/indra/llmessage/llpumpio.h9
-rw-r--r--linden/indra/newview/llinventorymodel.cpp533
-rw-r--r--linden/indra/newview/llinventorymodel.h38
-rw-r--r--linden/indra/newview/llstartup.cpp3
-rw-r--r--linden/indra/newview/llviewerinventory.cpp41
-rw-r--r--linden/indra/newview/llviewerregion.cpp6
12 files changed, 495 insertions, 237 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index a554e0a..37d5029 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,28 @@
12008-12-24 McCabe Maxsted <hakushakukun@gmail.com>
2
3 * linden/etc/message.xml:
4 Added inventory changes for one method of inventory
5 loss and upcoming new inv capabilities.
6 * linden/indra/llcommon/indra_constants.h:
7 Ditto.
8 * linden/indra/llinventory/llinventory.cpp:
9 Ditto.
10 * linden/indra/llmessage/lliosocket.cpp:
11 Ditto.
12 * linden/indra/llmessage/llpumpio.cpp:
13 Ditto.
14 * linden/indra/llmessage/llpumpio.h:
15 Ditto.
16 * linden/indra/newview/llinventorymodel.cpp:
17 Ditto.
18 * linden/indra/newview/llinventorymodel.h:
19 Ditto.
20 * linden/indra/newview/llstartup.cpp:
21 Ditto.
22 * linden/indra/newview/llviewerinventory.cpp:
23 Ditto.
24
25
12008-12-15 Jacek Antonelli <jacek.antonelli@gmail.com> 262008-12-15 Jacek Antonelli <jacek.antonelli@gmail.com>
2 27
3 * linden/install.xml: 28 * linden/install.xml:
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 @@
564 <boolean>true</boolean> 564 <boolean>true</boolean>
565 565
566 <key>FetchInventoryDescendents</key> 566 <key>FetchInventoryDescendents</key>
567 <boolean>false</boolean>
568
569 <key>WebFetchInventoryDescendents</key>
570 <boolean>true</boolean>
571
572 <key>FetchInventory</key>
573 <boolean>true</boolean>
574
575 <key>FetchLibDescendents</key>
576 <boolean>true</boolean>
577
578 <key>FetchLib</key>
567 <boolean>true</boolean> 579 <boolean>true</boolean>
568 </map> 580 </map>
569 581
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;
251const LLUUID LL_UUID_ALL_AGENTS("44e87126-e794-4ded-05b3-7c42da3d5cdb"); 251const LLUUID LL_UUID_ALL_AGENTS("44e87126-e794-4ded-05b3-7c42da3d5cdb");
252 252
253// Governor Linden's agent id. 253// Governor Linden's agent id.
254const LLUUID ALEXANDRIA_LINDEN_ID("ba2a564a-f0f1-4b82-9c61-b7520bfcd09f");
254const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); 255const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
255const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); 256const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1");
256// Maintenance's group id. 257// 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");
60static const std::string INV_FLAGS_LABEL("flags"); 60static const std::string INV_FLAGS_LABEL("flags");
61static const std::string INV_CREATION_DATE_LABEL("created_at"); 61static const std::string INV_CREATION_DATE_LABEL("created_at");
62 62
63// key used by agent-inventory-service
64static const std::string INV_ASSET_TYPE_LABEL_WS("type_default");
65static const std::string INV_FOLDER_ID_LABEL_WS("category_id");
63///---------------------------------------------------------------------------- 66///----------------------------------------------------------------------------
64/// Local function declarations, constants, enums, and typedefs 67/// Local function declarations, constants, enums, and typedefs
65///---------------------------------------------------------------------------- 68///----------------------------------------------------------------------------
@@ -949,11 +952,13 @@ LLSD LLInventoryItem::asLLSD() const
949 sd[INV_SHADOW_ID_LABEL] = shadow_id; 952 sd[INV_SHADOW_ID_LABEL] = shadow_id;
950 } 953 }
951 sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); 954 sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
955 sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
952 const char* inv_type_str = LLInventoryType::lookup(mInventoryType); 956 const char* inv_type_str = LLInventoryType::lookup(mInventoryType);
953 if(inv_type_str) 957 if(inv_type_str)
954 { 958 {
955 sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str; 959 sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
956 } 960 }
961 //sd[INV_FLAGS_LABEL] = (S32)mFlags;
957 sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); 962 sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
958 sd[INV_SALE_INFO_LABEL] = mSaleInfo; 963 sd[INV_SALE_INFO_LABEL] = mSaleInfo;
959 sd[INV_NAME_LABEL] = mName; 964 sd[INV_NAME_LABEL] = mName;
@@ -1026,17 +1031,40 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)
1026 w = INV_ASSET_TYPE_LABEL; 1031 w = INV_ASSET_TYPE_LABEL;
1027 if (sd.has(w)) 1032 if (sd.has(w))
1028 { 1033 {
1029 mType = LLAssetType::lookup(sd[w].asString()); 1034 if (sd[w].isString())
1035 {
1036 mType = LLAssetType::lookup(sd[w].asString().c_str());
1037 }
1038 else if (sd[w].isInteger())
1039 {
1040 S8 type = (U8)sd[w].asInteger();
1041 mType = static_cast<LLAssetType::EType>(type);
1042 }
1030 } 1043 }
1031 w = INV_INVENTORY_TYPE_LABEL; 1044 w = INV_INVENTORY_TYPE_LABEL;
1032 if (sd.has(w)) 1045 if (sd.has(w))
1033 { 1046 {
1034 mInventoryType = LLInventoryType::lookup(sd[w].asString()); 1047 if (sd[w].isString())
1048 {
1049 mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());
1050 }
1051 else if (sd[w].isInteger())
1052 {
1053 S8 type = (U8)sd[w].asInteger();
1054 mInventoryType = static_cast<LLInventoryType::EType>(type);
1055 }
1035 } 1056 }
1036 w = INV_FLAGS_LABEL; 1057 w = INV_FLAGS_LABEL;
1037 if (sd.has(w)) 1058 if (sd.has(w))
1038 { 1059 {
1039 mFlags = ll_U32_from_sd(sd[w]); 1060 if (sd[w].isBinary())
1061 {
1062 mFlags = ll_U32_from_sd(sd[w]);
1063 }
1064 else if(sd[w].isInteger())
1065 {
1066 mFlags = sd[w].asInteger();
1067 }
1040 } 1068 }
1041 w = INV_NAME_LABEL; 1069 w = INV_NAME_LABEL;
1042 if (sd.has(w)) 1070 if (sd.has(w))
@@ -1394,7 +1422,7 @@ bool LLInventoryCategory::fromLLSD(LLSD& sd)
1394{ 1422{
1395 std::string w; 1423 std::string w;
1396 1424
1397 w = INV_ITEM_ID_LABEL; 1425 w = INV_FOLDER_ID_LABEL_WS;
1398 if (sd.has(w)) 1426 if (sd.has(w))
1399 { 1427 {
1400 mUUID = sd[w]; 1428 mUUID = sd[w];
@@ -1410,6 +1438,13 @@ bool LLInventoryCategory::fromLLSD(LLSD& sd)
1410 S8 type = (U8)sd[w].asInteger(); 1438 S8 type = (U8)sd[w].asInteger();
1411 mPreferredType = static_cast<LLAssetType::EType>(type); 1439 mPreferredType = static_cast<LLAssetType::EType>(type);
1412 } 1440 }
1441 w = INV_ASSET_TYPE_LABEL_WS;
1442 if (sd.has(w))
1443 {
1444 S8 type = (U8)sd[w].asInteger();
1445 mPreferredType = static_cast<LLAssetType::EType>(type);
1446 }
1447
1413 w = INV_NAME_LABEL; 1448 w = INV_NAME_LABEL;
1414 if (sd.has(w)) 1449 if (sd.has(w))
1415 { 1450 {
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(
355 } 355 }
356 else if(APR_STATUS_IS_EAGAIN(status)) 356 else if(APR_STATUS_IS_EAGAIN(status))
357 { 357 {
358/*Commented out by Aura 9-9-8 for DEV-19961.
358 // everything is fine, but we can terminate this process pump. 359 // everything is fine, but we can terminate this process pump.
360
359 rv = STATUS_BREAK; 361 rv = STATUS_BREAK;
362*/
360 } 363 }
361 else 364 else
362 { 365 {
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)
269 return true; 269 return true;
270} 270}
271 271
272void LLPumpIO::adjustTimeoutSeconds(F32 delta)
273{
274 // If no chain is running, bail
275 if(current_chain_t() == mCurrentChain) return;
276 (*mCurrentChain).adjustTimeoutSeconds(delta);
277}
278
272static std::string events_2_string(apr_int16_t events) 279static std::string events_2_string(apr_int16_t events)
273{ 280{
274 std::ostringstream ostr; 281 std::ostringstream ostr;
@@ -1161,3 +1168,14 @@ void LLPumpIO::LLChainInfo::setTimeoutSeconds(F32 timeout)
1161 mTimer.stop(); 1168 mTimer.stop();
1162 } 1169 }
1163} 1170}
1171
1172void LLPumpIO::LLChainInfo::adjustTimeoutSeconds(F32 delta)
1173{
1174 LLMemType m1(LLMemType::MTYPE_IO_PUMP);
1175 if(mTimer.getStarted())
1176 {
1177 F64 expiry = mTimer.expiresAt();
1178 expiry += delta;
1179 mTimer.setExpiryAt(expiry);
1180 }
1181}
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:
166 bool setTimeoutSeconds(F32 timeout); 166 bool setTimeoutSeconds(F32 timeout);
167 167
168 /** 168 /**
169 * @brief Adjust the timeout of the running chain.
170 *
171 * This method has no effect if there is no timeout on the chain.
172 * @param delta The number of seconds to add to/remove from the timeout.
173 */
174 void adjustTimeoutSeconds(F32 delta);
175
176 /**
169 * @brief Set up file descriptors for for the running chain. 177 * @brief Set up file descriptors for for the running chain.
170 * @see rebuildPollset() 178 * @see rebuildPollset()
171 * 179 *
@@ -349,6 +357,7 @@ protected:
349 // methods 357 // methods
350 LLChainInfo(); 358 LLChainInfo();
351 void setTimeoutSeconds(F32 timeout); 359 void setTimeoutSeconds(F32 timeout);
360 void adjustTimeoutSeconds(F32 delta);
352 361
353 // basic member data 362 // basic member data
354 bool mInit; 363 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;
73F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f; 73F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f;
74BOOL LLInventoryModel::sTimelyFetchPending = FALSE; 74BOOL LLInventoryModel::sTimelyFetchPending = FALSE;
75LLFrameTimer LLInventoryModel::sFetchTimer; 75LLFrameTimer LLInventoryModel::sFetchTimer;
76LLInventoryModel::cat_map_t LLInventoryModel::sBulkFetchMap;
77S16 LLInventoryModel::sBulkFetchCount = 0; 76S16 LLInventoryModel::sBulkFetchCount = 0;
78 77
79// RN: for some reason, using std::queue in the header file confuses the compiler which things it's an xmlrpc_queue 78// 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<LLUUID> sFetchQueue;
85 84
86//BOOL decompress_file(const char* src_filename, const char* dst_filename); 85//BOOL decompress_file(const char* src_filename, const char* dst_filename);
87const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f; 86const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
88const S32 MAX_FETCH_RETRIES = 5; 87const S32 MAX_FETCH_RETRIES = 10;
89const char CACHE_FORMAT_STRING[] = "%s.inv"; 88const char CACHE_FORMAT_STRING[] = "%s.inv";
90const char* NEW_CATEGORY_NAME = "New Folder"; 89const char* NEW_CATEGORY_NAME = "New Folder";
91const char* NEW_CATEGORY_NAMES[LLAssetType::AT_COUNT] = 90const char* NEW_CATEGORY_NAMES[LLAssetType::AT_COUNT] =
@@ -990,13 +989,24 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer)
990// Call this method when it's time to update everyone on a new state, 989// Call this method when it's time to update everyone on a new state,
991// by default, the inventory model will not update observers 990// by default, the inventory model will not update observers
992// automatically. 991// automatically.
993void LLInventoryModel::notifyObservers() 992// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
993void LLInventoryModel::notifyObservers(const std::string service_name)
994{ 994{
995 for (observer_list_t::iterator iter = mObservers.begin(); 995 for (observer_list_t::iterator iter = mObservers.begin();
996 iter != mObservers.end(); ) 996 iter != mObservers.end(); )
997 { 997 {
998 LLInventoryObserver* observer = *iter; 998 LLInventoryObserver* observer = *iter;
999 observer->changed(mModifyMask); 999
1000 if (service_name.empty())
1001 {
1002 observer->changed(mModifyMask);
1003 }
1004 else
1005 {
1006 observer->mMessageName = service_name;
1007 observer->changed(mModifyMask);
1008 }
1009
1000 // safe way to incrament since changed may delete entries! (@!##%@!@&*!) 1010 // safe way to incrament since changed may delete entries! (@!##%@!@&*!)
1001 iter = mObservers.upper_bound(observer); 1011 iter = mObservers.upper_bound(observer);
1002 } 1012 }
@@ -1038,6 +1048,79 @@ void LLInventoryModel::mock(const LLUUID& root_id)
1038} 1048}
1039*/ 1049*/
1040 1050
1051//If we get back a normal response, handle it here
1052void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
1053{
1054 start_new_inventory_observer();
1055
1056 /*LLUUID agent_id;
1057 agent_id = content["agent_id"].asUUID();
1058 if(agent_id != gAgent.getID())
1059 {
1060 llwarns << "Got a inventory update for the wrong agent: " << agent_id
1061 << llendl;
1062 return;
1063 }*/
1064 item_array_t items;
1065 update_map_t update;
1066 S32 count = content["items"].size();
1067 bool all_one_folder = true;
1068 LLUUID folder_id;
1069 // Does this loop ever execute more than once? -Gigs
1070 for(S32 i = 0; i < count; ++i)
1071 {
1072 LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
1073 titem->unpackMessage(content["items"][i]);
1074
1075 lldebugs << "LLInventoryModel::messageUpdateCore() item id:"
1076 << titem->getUUID() << llendl;
1077 items.push_back(titem);
1078 // examine update for changes.
1079 LLViewerInventoryItem* itemp = gInventory.getItem(titem->getUUID());
1080 if(itemp)
1081 {
1082 if(titem->getParentUUID() == itemp->getParentUUID())
1083 {
1084 update[titem->getParentUUID()];
1085 }
1086 else
1087 {
1088 ++update[titem->getParentUUID()];
1089 --update[itemp->getParentUUID()];
1090 }
1091 }
1092 else
1093 {
1094 ++update[titem->getParentUUID()];
1095 }
1096 if (folder_id.isNull())
1097 {
1098 folder_id = titem->getParentUUID();
1099 }
1100 else
1101 {
1102 all_one_folder = false;
1103 }
1104 }
1105
1106 U32 changes = 0x0;
1107 //as above, this loop never seems to loop more than once per call
1108 for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
1109 {
1110 changes |= gInventory.updateItem(*it);
1111 }
1112 gInventory.notifyObservers("fetchinventory");
1113 gViewerWindow->getWindow()->decBusyCount();
1114}
1115
1116//If we get back an error (not found, etc...), handle it here
1117void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason)
1118{
1119 llinfos << "fetchInventory::error "
1120 << status << ": " << reason << llendl;
1121 gInventory.notifyObservers("fetchinventory");
1122}
1123
1041void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) 1124void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
1042{ 1125{
1043 LLViewerInventoryCategory* cat = getCategory(folder_id); 1126 LLViewerInventoryCategory* cat = getCategory(folder_id);
@@ -1065,21 +1148,31 @@ void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id)
1065} 1148}
1066 1149
1067//Initialize statics. 1150//Initialize statics.
1068LLAlertDialog* LLInventoryModel::fetchDescendentsResponder::sRetryDialog=NULL;
1069LLSD LLInventoryModel::fetchDescendentsResponder::sRetrySD;
1070
1071bool LLInventoryModel::isBulkFetchProcessingComplete() 1151bool LLInventoryModel::isBulkFetchProcessingComplete()
1072{ 1152{
1073 return ( (sFetchQueue.empty() 1153 return ( (sFetchQueue.empty()
1074 && sBulkFetchMap.empty() 1154 && sBulkFetchCount<=0) ? TRUE : FALSE ) ;
1075 && sBulkFetchCount==0) ? TRUE : FALSE ) ;
1076} 1155}
1077 1156
1157class fetchDescendentsResponder: public LLHTTPClient::Responder
1158{
1159 public:
1160 fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
1161 //fetchDescendentsResponder() {};
1162 void result(const LLSD& content);
1163 void error(U32 status, const std::string& reason);
1164 public:
1165 typedef std::vector<LLViewerInventoryCategory*> folder_ref_t;
1166 protected:
1167 LLSD mRequestSD;
1168};
1169
1078//If we get back a normal response, handle it here 1170//If we get back a normal response, handle it here
1079void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content) 1171void fetchDescendentsResponder::result(const LLSD& content)
1080{ 1172{
1081 if (content.has("folders")) 1173 if (content.has("folders"))
1082 { 1174 {
1175
1083 for(LLSD::array_const_iterator folder_it = content["folders"].beginArray(); 1176 for(LLSD::array_const_iterator folder_it = content["folders"].beginArray();
1084 folder_it != content["folders"].endArray(); 1177 folder_it != content["folders"].endArray();
1085 ++folder_it) 1178 ++folder_it)
@@ -1087,19 +1180,54 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
1087 LLSD folder_sd = *folder_it; 1180 LLSD folder_sd = *folder_it;
1088 1181
1089 1182
1090 LLUUID agent_id = folder_sd["agent-id"]; 1183 //LLUUID agent_id = folder_sd["agent_id"];
1091 1184
1092 if(agent_id != gAgent.getID()) //This should never happen. 1185 //if(agent_id != gAgent.getID()) //This should never happen.
1093 { 1186 //{
1094 llwarns << "Got a UpdateInventoryItem for the wrong agent." 1187 // llwarns << "Got a UpdateInventoryItem for the wrong agent."
1095 << llendl; 1188 // << llendl;
1096 break; 1189 // break;
1097 } 1190 //}
1098 LLUUID parent_id = folder_sd["folder-id"]; 1191
1099 LLUUID owner_id = folder_sd["owner-id"]; 1192 LLUUID parent_id = folder_sd["folder_id"];
1193 LLUUID owner_id = folder_sd["owner_id"];
1100 S32 version = (S32)folder_sd["version"].asInteger(); 1194 S32 version = (S32)folder_sd["version"].asInteger();
1101 S32 descendents = (S32)folder_sd["descendents"].asInteger(); 1195 S32 descendents = (S32)folder_sd["descendents"].asInteger();
1102 LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id); 1196 LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
1197
1198 if (parent_id.isNull())
1199 {
1200 LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
1201 for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
1202 item_it != folder_sd["items"].endArray();
1203 ++item_it)
1204 {
1205 LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
1206 if (lost_uuid.notNull())
1207 {
1208 LLSD item = *item_it;
1209 titem->unpackMessage(item);
1210
1211 LLInventoryModel::update_list_t update;
1212 LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
1213 update.push_back(new_folder);
1214 gInventory.accountForUpdate(update);
1215
1216 titem->setParent(lost_uuid);
1217 titem->updateParentOnServer(FALSE);
1218 gInventory.updateItem(titem);
1219 gInventory.notifyObservers("fetchDescendents");
1220
1221 }
1222 }
1223 }
1224
1225 LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id);
1226 if (!pcat)
1227 {
1228 continue;
1229 }
1230
1103 for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray(); 1231 for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray();
1104 category_it != folder_sd["categories"].endArray(); 1232 category_it != folder_sd["categories"].endArray();
1105 ++category_it) 1233 ++category_it)
@@ -1107,7 +1235,7 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
1107 LLSD category = *category_it; 1235 LLSD category = *category_it;
1108 tcategory->fromLLSD(category); 1236 tcategory->fromLLSD(category);
1109 1237
1110 if (sFullFetchStarted) 1238 if (LLInventoryModel::sFullFetchStarted)
1111 { 1239 {
1112 sFetchQueue.push_back(tcategory->getUUID()); 1240 sFetchQueue.push_back(tcategory->getUUID());
1113 } 1241 }
@@ -1139,37 +1267,37 @@ void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content)
1139 } 1267 }
1140 } 1268 }
1141 1269
1142 if (content.has("bad-folders")) 1270 if (content.has("bad_folders"))
1143 { 1271 {
1144 for(LLSD::array_const_iterator folder_it = content["bad-folders"].beginArray(); 1272 for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray();
1145 folder_it != content["bad-folders"].endArray(); 1273 folder_it != content["bad_folders"].endArray();
1146 ++folder_it) 1274 ++folder_it)
1147 { 1275 {
1148 LLSD folder_sd = *folder_it; 1276 LLSD folder_sd = *folder_it;
1149 1277
1150 //These folders failed on the dataserver. We probably don't want to retry them. 1278 //These folders failed on the dataserver. We probably don't want to retry them.
1151 llinfos << "Folder " << folder_sd["folder-id"].asString() 1279 llinfos << "Folder " << folder_sd["folder_id"].asString()
1152 << "Error: " << folder_sd["error"].asString() << llendl; 1280 << "Error: " << folder_sd["error"].asString() << llendl;
1153 } 1281 }
1154 } 1282 }
1155 1283
1156 LLInventoryModel::incrBulkFetch(-1); 1284 LLInventoryModel::incrBulkFetch(-1);
1157 1285
1158 if (isBulkFetchProcessingComplete()) 1286 if (LLInventoryModel::isBulkFetchProcessingComplete())
1159 { 1287 {
1160 llinfos << "Inventory fetch completed" << llendl; 1288 llinfos << "Inventory fetch completed" << llendl;
1161 if (sFullFetchStarted) 1289 if (LLInventoryModel::sFullFetchStarted)
1162 { 1290 {
1163 sAllFoldersFetched = TRUE; 1291 LLInventoryModel::sAllFoldersFetched = TRUE;
1164 } 1292 }
1165 stopBackgroundFetch(); 1293 LLInventoryModel::stopBackgroundFetch();
1166 } 1294 }
1167 1295
1168 gInventory.notifyObservers(); 1296 gInventory.notifyObservers("fetchDescendents");
1169} 1297}
1170 1298
1171//If we get back an error (not found, etc...), handle it here 1299//If we get back an error (not found, etc...), handle it here
1172void LLInventoryModel::fetchDescendentsResponder::error(U32 status, const std::string& reason) 1300void fetchDescendentsResponder::error(U32 status, const std::string& reason)
1173{ 1301{
1174 llinfos << "fetchDescendentsResponder::error " 1302 llinfos << "fetchDescendentsResponder::error "
1175 << status << ": " << reason << llendl; 1303 << status << ": " << reason << llendl;
@@ -1183,61 +1311,22 @@ void LLInventoryModel::fetchDescendentsResponder::error(U32 status, const std::s
1183 ++folder_it) 1311 ++folder_it)
1184 { 1312 {
1185 LLSD folder_sd = *folder_it; 1313 LLSD folder_sd = *folder_it;
1186 sRetrySD["folders"].append(folder_sd); 1314 LLUUID folder_id = folder_sd["folder_id"];
1187 } 1315 sFetchQueue.push_front(folder_id);
1188 sMinTimeBetweenFetches = 10.0f; //Add 10 seconds for every time out in this sequence.
1189
1190 if (!sRetryDialog) //The dialog isn't up. Prompt the resident.
1191 {
1192 sRetryDialog = gViewerWindow->alertXml("RetryFetchInventoryDescendents", onClickRetry, this);
1193 } 1316 }
1194 } 1317 }
1195 else 1318 else
1196 { 1319 {
1197 if (isBulkFetchProcessingComplete()) 1320 if (LLInventoryModel::isBulkFetchProcessingComplete())
1198 { 1321 {
1199 if (sFullFetchStarted) 1322 if (LLInventoryModel::sFullFetchStarted)
1200 { 1323 {
1201 sAllFoldersFetched = TRUE; 1324 LLInventoryModel::sAllFoldersFetched = TRUE;
1202 } 1325 }
1203 stopBackgroundFetch(); 1326 LLInventoryModel::stopBackgroundFetch();
1204 } 1327 }
1205 } 1328 }
1206 gInventory.notifyObservers(); 1329 gInventory.notifyObservers("fetchDescendents");
1207}
1208
1209void LLInventoryModel::fetchDescendentsResponder::onClickRetry(S32 option, void* userdata)
1210{
1211 if (option == 0)
1212 {
1213 std::string url;
1214
1215 LLViewerRegion * agent_region = gAgent.getRegion();
1216 if (agent_region)
1217 {
1218 url = agent_region->getCapability("FetchInventoryDescendents");
1219 }
1220
1221 if (!url.empty()) //Capability found. Build up LLSD and use it.
1222 {
1223 LLSD body = sRetrySD;
1224 LLInventoryModel::incrBulkFetch(1);
1225 LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body),300);
1226 }
1227 }
1228 else
1229 {
1230 if (isBulkFetchProcessingComplete())
1231 {
1232 if (sFullFetchStarted)
1233 {
1234 sAllFoldersFetched = TRUE;
1235 }
1236 stopBackgroundFetch();
1237 }
1238 }
1239 sRetryDialog=NULL;
1240 sRetrySD.clear();
1241} 1330}
1242 1331
1243//static Bundle up a bunch of requests to send all at once. 1332//static Bundle up a bunch of requests to send all at once.
@@ -1250,7 +1339,7 @@ void LLInventoryModel::bulkFetch(std::string url)
1250 1339
1251 S16 max_concurrent_fetches=8; 1340 S16 max_concurrent_fetches=8;
1252 F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. 1341 F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely.
1253 if (sMinTimeBetweenFetches <= new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above. 1342 if (sMinTimeBetweenFetches < new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above.
1254 1343
1255 if(gDisconnected 1344 if(gDisconnected
1256 || sBulkFetchCount > max_concurrent_fetches 1345 || sBulkFetchCount > max_concurrent_fetches
@@ -1263,84 +1352,83 @@ void LLInventoryModel::bulkFetch(std::string url)
1263 //redundant requests. When we get rid of the old code entirely, we can change 1352 //redundant requests. When we get rid of the old code entirely, we can change
1264 //the dequeue to a map. In the new model, there is no benefit to queue order. 1353 //the dequeue to a map. In the new model, there is no benefit to queue order.
1265 U32 folder_count=0; 1354 U32 folder_count=0;
1266 U32 max_batch_size=10; 1355 U32 max_batch_size=5;
1267 while( !(sFetchQueue.empty() ) ) 1356
1268 { 1357 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
1269 LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front()); 1358
1270 1359 LLSD body;
1271 if (cat) 1360 LLSD body_lib;
1272 { 1361 while( !(sFetchQueue.empty() ) && (folder_count < max_batch_size) )
1273 if ( !gInventory.isCategoryComplete(cat->getUUID()) ) //grab this folder. 1362 {
1274 { 1363 if (sFetchQueue.front().isNull()) //DEV-17797
1275 sBulkFetchMap[(cat->getUUID())] = cat; 1364 {
1276 } 1365 LLSD folder_sd;
1277 else if (sFullFetchStarted) 1366 folder_sd["folder_id"] = LLUUID::null.asString();
1278 { //Already have this folder but append child folders to list. 1367 folder_sd["owner_id"] = gAgent.getID();
1279 // add all children to queue 1368 folder_sd["sort_order"] = (LLSD::Integer)sort_order;
1280 parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID()); 1369 folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE;
1281 if (cat_it != gInventory.mParentChildCategoryTree.end()) 1370 folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
1282 { 1371 body["folders"].append(folder_sd);
1283 cat_array_t* child_categories = cat_it->second; 1372 folder_count++;
1284 1373 }
1285 for (S32 child_num = 0; child_num < child_categories->count(); child_num++) 1374 else
1286 { 1375 {
1287 sFetchQueue.push_back(child_categories->get(child_num)->getUUID()); 1376
1288 }
1289 }
1290 1377
1291 } 1378 LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front());
1292 } 1379
1380 if (cat)
1381 {
1382 if ( LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion())
1383 {
1384 LLSD folder_sd;
1385 folder_sd["folder_id"] = cat->getUUID();
1386 folder_sd["owner_id"] = cat->getOwnerID();
1387 folder_sd["sort_order"] = (LLSD::Integer)sort_order;
1388 folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted;
1389 folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
1390
1391 if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID())
1392 body_lib["folders"].append(folder_sd);
1393 else
1394 body["folders"].append(folder_sd);
1395 folder_count++;
1396 }
1397 if (sFullFetchStarted)
1398 { //Already have this folder but append child folders to list.
1399 // add all children to queue
1400 parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID());
1401 if (cat_it != gInventory.mParentChildCategoryTree.end())
1402 {
1403 cat_array_t* child_categories = cat_it->second;
1404
1405 for (S32 child_num = 0; child_num < child_categories->count(); child_num++)
1406 {
1407 sFetchQueue.push_back(child_categories->get(child_num)->getUUID());
1408 }
1409 }
1410
1411 }
1412 }
1413 }
1293 sFetchQueue.pop_front(); 1414 sFetchQueue.pop_front();
1294 } 1415 }
1295 1416
1296
1297 if (!sBulkFetchMap.empty()) //There's stuff to fetch.
1298 {
1299 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
1300
1301 LLSD body;
1302
1303 cat_map_t::iterator iter=sBulkFetchMap.begin();
1304 while( iter!=sBulkFetchMap.end() && (folder_count < max_batch_size) )
1305 {
1306 LLViewerInventoryCategory* cat = iter->second;
1307
1308 if (cat && !gInventory.isCategoryComplete(cat->getUUID()) ) //Category exists
1309 {
1310 BOOL fetchItems=TRUE;
1311 if ( sFullFetchStarted
1312 && gInventory.isCategoryComplete(cat->getUUID()) )
1313 {
1314 fetchItems=FALSE;
1315 }
1316
1317 LLSD folder_sd;
1318 folder_sd["folder-id"] = cat->getUUID();
1319 folder_sd["owner-id"] = cat->getOwnerID();
1320 folder_sd["sort-order"] = (LLSD::Integer)sort_order;
1321 folder_sd["fetch-folders"] = (LLSD::Boolean)sFullFetchStarted;
1322 folder_sd["fetch-items"] = (LLSD::Boolean)fetchItems;
1323 body["folders"].append(folder_sd);
1324
1325 folder_count++;
1326 }
1327 sBulkFetchMap.erase(iter);
1328 iter=sBulkFetchMap.begin();
1329 }
1330
1331 if (iter == sBulkFetchMap.end()) sBulkFetchMap.clear();
1332
1333 if (folder_count > 0) 1417 if (folder_count > 0)
1334 { 1418 {
1335 sBulkFetchCount++; 1419 sBulkFetchCount++;
1336 1420 if (body["folders"].size())
1337 LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body)); 1421 {
1422 LLHTTPClient::post(url, body, new fetchDescendentsResponder(body),300.0);
1423 }
1424 if (body_lib["folders"].size())
1425 {
1426 std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents");
1427 LLHTTPClient::post(url_lib, body_lib, new fetchDescendentsResponder(body_lib),300.0);
1428 }
1338 sFetchTimer.reset(); 1429 sFetchTimer.reset();
1339 } 1430 }
1340 1431 else if (isBulkFetchProcessingComplete())
1341 }
1342
1343 if (isBulkFetchProcessingComplete())
1344 { 1432 {
1345 if (sFullFetchStarted) 1433 if (sFullFetchStarted)
1346 { 1434 {
@@ -1391,6 +1479,14 @@ void LLInventoryModel::startBackgroundFetch(const LLUUID& cat_id)
1391} 1479}
1392 1480
1393//static 1481//static
1482void LLInventoryModel::findLostItems()
1483{
1484 sBackgroundFetchActive = TRUE;
1485 sFetchQueue.push_back(LLUUID::null);
1486 gIdleCallbacks.addFunction(&LLInventoryModel::backgroundFetch, NULL);
1487}
1488
1489//static
1394void LLInventoryModel::stopBackgroundFetch() 1490void LLInventoryModel::stopBackgroundFetch()
1395{ 1491{
1396 if (sBackgroundFetchActive) 1492 if (sBackgroundFetchActive)
@@ -1409,14 +1505,7 @@ void LLInventoryModel::backgroundFetch(void*)
1409 if (sBackgroundFetchActive) 1505 if (sBackgroundFetchActive)
1410 { 1506 {
1411 //If we'll be using the capability, we'll be sending batches and the background thing isn't as important. 1507 //If we'll be using the capability, we'll be sending batches and the background thing isn't as important.
1412 std::string url; 1508 std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
1413
1414 LLViewerRegion * agent_region = gAgent.getRegion();
1415 if (agent_region)
1416 {
1417 url = agent_region->getCapability("FetchInventoryDescendents");
1418 }
1419
1420 if (!url.empty()) 1509 if (!url.empty())
1421 { 1510 {
1422 bulkFetch(url); 1511 bulkFetch(url);
@@ -3373,12 +3462,72 @@ bool LLInventoryFetchObserver::isEverythingComplete() const
3373 return mIncomplete.empty(); 3462 return mIncomplete.empty();
3374} 3463}
3375 3464
3465void fetch_items_from_llsd(const LLSD& items_llsd)
3466{
3467 if (!items_llsd.size()) return;
3468 LLSD body;
3469 body[0]["cap_name"] = "FetchInventory";
3470 body[1]["cap_name"] = "FetchLib";
3471 for (S32 i=0; i<items_llsd.size();i++)
3472 {
3473 if (items_llsd[i]["owner_id"].asString() == gAgent.getID().asString())
3474 {
3475 body[0]["items"].append(items_llsd[i]);
3476 continue;
3477 }
3478 if (items_llsd[i]["owner_id"].asString() == ALEXANDRIA_LINDEN_ID.asString())
3479 {
3480 body[1]["items"].append(items_llsd[i]);
3481 continue;
3482 }
3483 }
3484
3485 for (S32 i=0; i<body.size(); i++)
3486 {
3487 if (0 >= body[i].size()) continue;
3488 std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
3489
3490 if (!url.empty())
3491 {
3492 body[i]["agent_id"] = gAgent.getID();
3493 LLHTTPClient::post(url, body[i], new LLInventoryModel::fetchInventoryResponder(body[i]));
3494 break;
3495 }
3496
3497 LLMessageSystem* msg = gMessageSystem;
3498 BOOL start_new_message = TRUE;
3499 for (S32 j=0; j<body[i]["items"].size(); j++)
3500 {
3501 LLSD item_entry = body[i]["items"][j];
3502 if(start_new_message)
3503 {
3504 start_new_message = FALSE;
3505 msg->newMessageFast(_PREHASH_FetchInventory);
3506 msg->nextBlockFast(_PREHASH_AgentData);
3507 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
3508 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3509 }
3510 msg->nextBlockFast(_PREHASH_InventoryData);
3511 msg->addUUIDFast(_PREHASH_OwnerID, item_entry["owner_id"].asUUID());
3512 msg->addUUIDFast(_PREHASH_ItemID, item_entry["item_id"].asUUID());
3513 if(msg->isSendFull(NULL))
3514 {
3515 start_new_message = TRUE;
3516 gAgent.sendReliableMessage();
3517 }
3518 }
3519 if(!start_new_message)
3520 {
3521 gAgent.sendReliableMessage();
3522 }
3523 }
3524}
3525
3376void LLInventoryFetchObserver::fetchItems( 3526void LLInventoryFetchObserver::fetchItems(
3377 const LLInventoryFetchObserver::item_ref_t& ids) 3527 const LLInventoryFetchObserver::item_ref_t& ids)
3378{ 3528{
3379 LLMessageSystem* msg = gMessageSystem;
3380 BOOL start_new_message = TRUE;
3381 LLUUID owner_id; 3529 LLUUID owner_id;
3530 LLSD items_llsd;
3382 for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it) 3531 for(item_ref_t::const_iterator it = ids.begin(); it < ids.end(); ++it)
3383 { 3532 {
3384 LLViewerInventoryItem* item = gInventory.getItem(*it); 3533 LLViewerInventoryItem* item = gInventory.getItem(*it);
@@ -3400,31 +3549,18 @@ void LLInventoryFetchObserver::fetchItems(
3400 // assume it's agent inventory. 3549 // assume it's agent inventory.
3401 owner_id = gAgent.getID(); 3550 owner_id = gAgent.getID();
3402 } 3551 }
3403 3552
3404 // It's incomplete, so put it on the incomplete container, and 3553 // It's incomplete, so put it on the incomplete container, and
3405 // pack this on the message. 3554 // pack this on the message.
3406 mIncomplete.push_back(*it); 3555 mIncomplete.push_back(*it);
3407 if(start_new_message) 3556
3408 { 3557 // Prepare the data to fetch
3409 start_new_message = FALSE; 3558 LLSD item_entry;
3410 msg->newMessageFast(_PREHASH_FetchInventory); 3559 item_entry["owner_id"] = owner_id;
3411 msg->nextBlockFast(_PREHASH_AgentData); 3560 item_entry["item_id"] = (*it);
3412 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 3561 items_llsd.append(item_entry);
3413 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3414 }
3415 msg->nextBlockFast(_PREHASH_InventoryData);
3416 msg->addUUIDFast(_PREHASH_OwnerID, owner_id);
3417 msg->addUUIDFast(_PREHASH_ItemID, (*it));
3418 if(msg->isSendFull(NULL))
3419 {
3420 start_new_message = TRUE;
3421 gAgent.sendReliableMessage();
3422 }
3423 }
3424 if(!start_new_message)
3425 {
3426 gAgent.sendReliableMessage();
3427 } 3562 }
3563 fetch_items_from_llsd(items_llsd);
3428} 3564}
3429 3565
3430// virtual 3566// virtual
@@ -3579,9 +3715,8 @@ void LLInventoryFetchComboObserver::fetch(
3579 // descendent of an incomplete folder because the item will show 3715 // descendent of an incomplete folder because the item will show
3580 // up in an inventory descendents message soon enough so we do not 3716 // up in an inventory descendents message soon enough so we do not
3581 // have to fetch it individually. 3717 // have to fetch it individually.
3718 LLSD items_llsd;
3582 LLUUID owner_id; 3719 LLUUID owner_id;
3583 LLMessageSystem* msg = gMessageSystem;
3584 bool start_new_message = true;
3585 for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit) 3720 for(item_ref_t::const_iterator iit = item_ids.begin(); iit != item_ids.end(); ++iit)
3586 { 3721 {
3587 LLViewerInventoryItem* item = gInventory.getItem(*iit); 3722 LLViewerInventoryItem* item = gInventory.getItem(*iit);
@@ -3604,33 +3739,17 @@ void LLInventoryFetchComboObserver::fetch(
3604 } 3739 }
3605 if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end()) 3740 if(std::find(mIncompleteFolders.begin(), mIncompleteFolders.end(), item->getParentUUID()) == mIncompleteFolders.end())
3606 { 3741 {
3607 lldebugs << "fetching item " << *iit << llendl; 3742 LLSD item_entry;
3608 if(start_new_message) 3743 item_entry["owner_id"] = owner_id;
3609 { 3744 item_entry["item_id"] = (*iit);
3610 start_new_message = false; 3745 items_llsd.append(item_entry);
3611 msg->newMessageFast(_PREHASH_FetchInventory);
3612 msg->nextBlockFast(_PREHASH_AgentData);
3613 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
3614 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3615 }
3616 msg->nextBlockFast(_PREHASH_InventoryData);
3617 msg->addUUIDFast(_PREHASH_OwnerID, owner_id);
3618 msg->addUUIDFast(_PREHASH_ItemID, (*iit));
3619 if(msg->isSendFullFast(_PREHASH_InventoryData))
3620 {
3621 start_new_message = true;
3622 gAgent.sendReliableMessage();
3623 }
3624 } 3746 }
3625 else 3747 else
3626 { 3748 {
3627 lldebugs << "not worrying about " << *iit << llendl; 3749 lldebugs << "not worrying about " << *iit << llendl;
3628 } 3750 }
3629 } 3751 }
3630 if(!start_new_message) 3752 fetch_items_from_llsd(items_llsd);
3631 {
3632 gAgent.sendReliableMessage();
3633 }
3634} 3753}
3635 3754
3636void LLInventoryExistenceObserver::watchItem(const LLUUID& id) 3755void LLInventoryExistenceObserver::watchItem(const LLUUID& id)
@@ -3676,7 +3795,17 @@ void LLInventoryAddedObserver::changed(U32 mask)
3676 // the network, figure out which item was updated. 3795 // the network, figure out which item was updated.
3677 // Code from Gigs Taggert, sin allowed by JC. 3796 // Code from Gigs Taggert, sin allowed by JC.
3678 LLMessageSystem* msg = gMessageSystem; 3797 LLMessageSystem* msg = gMessageSystem;
3679 std::string msg_name = msg->getMessageName(); 3798
3799 std::string msg_name;
3800 if (mMessageName.empty())
3801 {
3802 msg_name = msg->getMessageName();
3803 }
3804 else
3805 {
3806 msg_name = mMessageName;
3807 }
3808
3680 if (msg_name.empty()) 3809 if (msg_name.empty())
3681 { 3810 {
3682 return; 3811 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:
69 }; 69 };
70 virtual ~LLInventoryObserver() {}; 70 virtual ~LLInventoryObserver() {};
71 virtual void changed(U32 mask) = 0; 71 virtual void changed(U32 mask) = 0;
72 std::string mMessageName; // used by Agent Inventory Service only. [DEV-20328]
72}; 73};
73 74
74//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -110,20 +111,17 @@ public:
110 LLInventoryModel(); 111 LLInventoryModel();
111 ~LLInventoryModel(); 112 ~LLInventoryModel();
112 113
113 class fetchDescendentsResponder: public LLHTTPClient::Responder 114 class fetchInventoryResponder: public LLHTTPClient::Responder
114 { 115 {
115 public: 116 public:
116 fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; 117 fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
117 void result(const LLSD& content); 118 void result(const LLSD& content);
118 void error(U32 status, const std::string& reason); 119 void error(U32 status, const std::string& reason);
119 static void onClickRetry(S32 option, void* userdata); 120
120 static void appendRetryList(LLSD retry_sd); 121 public:
121 public: 122 typedef std::vector<LLViewerInventoryCategory*> folder_ref_t;
122 typedef std::vector<LLViewerInventoryCategory*> folder_ref_t; 123 protected:
123 protected: 124 LLSD mRequestSD;
124 LLSD mRequestSD;
125 static LLSD sRetrySD;
126 static LLAlertDialog *sRetryDialog;
127 }; 125 };
128 126
129 // 127 //
@@ -268,7 +266,8 @@ public:
268 // Call this method when it's time to update everyone on a new 266 // Call this method when it's time to update everyone on a new
269 // state, by default, the inventory model will not update 267 // state, by default, the inventory model will not update
270 // observers automatically. 268 // observers automatically.
271 void notifyObservers(); 269 // The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
270 void notifyObservers(const std::string service_name="");
272 271
273 // This allows outsiders to tell the inventory if something has 272 // This allows outsiders to tell the inventory if something has
274 // been changed 'under the hood', but outside the control of the 273 // been changed 'under the hood', but outside the control of the
@@ -370,7 +369,7 @@ public:
370 // start and stop background breadth-first fetching of inventory contents 369 // start and stop background breadth-first fetching of inventory contents
371 // this gets triggered when performing a filter-search 370 // this gets triggered when performing a filter-search
372 static void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null); // start fetch process 371 static void startBackgroundFetch(const LLUUID& cat_id = LLUUID::null); // start fetch process
373 static void stopBackgroundFetch(); // stop fetch process 372 static void findLostItems();
374 static BOOL backgroundFetchActive(); 373 static BOOL backgroundFetchActive();
375 static bool isEverythingFetched(); 374 static bool isEverythingFetched();
376 static void backgroundFetch(void*); // background fetch idle function 375 static void backgroundFetch(void*); // background fetch idle function
@@ -419,7 +418,6 @@ protected:
419 static void processInventoryDescendents(LLMessageSystem* msg, void**); 418 static void processInventoryDescendents(LLMessageSystem* msg, void**);
420 static void processMoveInventoryItem(LLMessageSystem* msg, void**); 419 static void processMoveInventoryItem(LLMessageSystem* msg, void**);
421 static void processFetchInventoryReply(LLMessageSystem* msg, void**); 420 static void processFetchInventoryReply(LLMessageSystem* msg, void**);
422 static bool isBulkFetchProcessingComplete();
423 421
424 bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting); 422 bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting);
425 423
@@ -460,11 +458,8 @@ protected:
460 observer_list_t mObservers; 458 observer_list_t mObservers;
461 459
462 // completing the fetch once per session should be sufficient 460 // completing the fetch once per session should be sufficient
463 static cat_map_t sBulkFetchMap;
464 static BOOL sBackgroundFetchActive; 461 static BOOL sBackgroundFetchActive;
465 static BOOL sTimelyFetchPending; 462 static BOOL sTimelyFetchPending;
466 static BOOL sAllFoldersFetched;
467 static BOOL sFullFetchStarted;
468 static S32 sNumFetchRetries; 463 static S32 sNumFetchRetries;
469 static LLFrameTimer sFetchTimer; 464 static LLFrameTimer sFetchTimer;
470 static F32 sMinTimeBetweenFetches; 465 static F32 sMinTimeBetweenFetches;
@@ -477,6 +472,11 @@ protected:
477public: 472public:
478 // *NOTE: DEBUG functionality 473 // *NOTE: DEBUG functionality
479 void dumpInventory(); 474 void dumpInventory();
475 static bool isBulkFetchProcessingComplete();
476 static void stopBackgroundFetch(); // stop fetch process
477
478 static BOOL sFullFetchStarted;
479 static BOOL sAllFoldersFetched;
480}; 480};
481 481
482// a special inventory model for the agent 482// 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()
2251 } 2251 }
2252 } 2252 }
2253 2253
2254 //DEV-17797. get null folder. Any items found here moved to Lost and Found
2255 LLInventoryModel::findLostItems();
2256
2254 LLStartUp::setStartupState( STATE_PRECACHE ); 2257 LLStartUp::setStartupState( STATE_PRECACHE );
2255 timeout.reset(); 2258 timeout.reset();
2256 return FALSE; 2259 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
196{ 196{
197 if(!mIsComplete) 197 if(!mIsComplete)
198 { 198 {
199 LLMessageSystem* msg = gMessageSystem; 199 std::string url;
200 msg->newMessage("FetchInventory"); 200
201 msg->nextBlock("AgentData"); 201 if( ALEXANDRIA_LINDEN_ID.getString() == mPermissions.getOwner().getString())
202 msg->addUUID("AgentID", gAgent.getID()); 202 url = gAgent.getRegion()->getCapability("FetchLib");
203 msg->addUUID("SessionID", gAgent.getSessionID()); 203 else
204 msg->nextBlock("InventoryData"); 204 url = gAgent.getRegion()->getCapability("FetchInventory");
205 msg->addUUID("OwnerID", mPermissions.getOwner()); 205
206 msg->addUUID("ItemID", mUUID); 206 if (!url.empty())
207 gAgent.sendReliableMessage(); 207 {
208 LLSD body;
209 body["agent_id"] = gAgent.getID();
210 body["items"][0]["owner_id"] = mPermissions.getOwner();
211 body["items"][0]["item_id"] = mUUID;
212
213 LLHTTPClient::post(url, body, new LLInventoryModel::fetchInventoryResponder(body));
214 }
215 else
216 {
217 LLMessageSystem* msg = gMessageSystem;
218 msg->newMessage("FetchInventory");
219 msg->nextBlock("AgentData");
220 msg->addUUID("AgentID", gAgent.getID());
221 msg->addUUID("SessionID", gAgent.getSessionID());
222 msg->nextBlock("InventoryData");
223 msg->addUUID("OwnerID", mPermissions.getOwner());
224 msg->addUUID("ItemID", mUUID);
225 gAgent.sendReliableMessage();
226 }
208 } 227 }
209 else 228 else
210 { 229 {
@@ -441,7 +460,7 @@ bool LLViewerInventoryCategory::fetchDescendents()
441 // This comes from LLInventoryFilter from llfolderview.h 460 // This comes from LLInventoryFilter from llfolderview.h
442 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1; 461 U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
443 462
444 std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents"); 463 std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
445 464
446 if (!url.empty()) //Capability found. Build up LLSD and use it. 465 if (!url.empty()) //Capability found. Build up LLSD and use it.
447 { 466 {
@@ -449,7 +468,7 @@ bool LLViewerInventoryCategory::fetchDescendents()
449 } 468 }
450 else 469 else
451 { //Deprecated, but if we don't have a capability, use the old system. 470 { //Deprecated, but if we don't have a capability, use the old system.
452 llinfos << "FetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl; 471 llinfos << "WebFetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl;
453 LLMessageSystem* msg = gMessageSystem; 472 LLMessageSystem* msg = gMessageSystem;
454 msg->newMessage("FetchInventoryDescendents"); 473 msg->newMessage("FetchInventoryDescendents");
455 msg->nextBlock("AgentData"); 474 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)
1391 capabilityNames.append("DispatchRegionInfo"); 1391 capabilityNames.append("DispatchRegionInfo");
1392 capabilityNames.append("EstateChangeInfo"); 1392 capabilityNames.append("EstateChangeInfo");
1393 capabilityNames.append("EventQueueGet"); 1393 capabilityNames.append("EventQueueGet");
1394 capabilityNames.append("FetchInventoryDescendents"); 1394 capabilityNames.append("FetchInventory");
1395 capabilityNames.append("WebFetchInventoryDescendents");
1396 capabilityNames.append("FetchLib");
1397 capabilityNames.append("FetchLibDescendents");
1395 capabilityNames.append("GroupProposalBallot"); 1398 capabilityNames.append("GroupProposalBallot");
1399 capabilityNames.append("HomeLocation");
1396 capabilityNames.append("MapLayer"); 1400 capabilityNames.append("MapLayer");
1397 capabilityNames.append("MapLayerGod"); 1401 capabilityNames.append("MapLayerGod");
1398 capabilityNames.append("NewFileAgentInventory"); 1402 capabilityNames.append("NewFileAgentInventory");