From 0281fb05f9da8adc2e9c19fcd90075f82ccd3a1a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Apr 2020 19:44:14 +0300 Subject: SL-1577 Inventory desync on copying content of task --- indra/newview/llinventorymodel.cpp | 64 +++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c49d61df31..8f078f8eca 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -678,17 +678,59 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv LLUUID categoryId = result["folder_id"].asUUID(); - // Add the category to the internal representation - LLPointer cat = new LLViewerInventoryCategory(categoryId, - result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(), - result["name"].asString(), gAgent.getID()); - - cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 - cat->setDescendentCount(0); - LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); - - accountForUpdate(update); - updateCategory(cat); + LLViewerInventoryCategory* folderp = gInventory.getCategory(categoryId); + if (!folderp) + { + // Add the category to the internal representation + LLPointer cat = new LLViewerInventoryCategory(categoryId, + result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(), + result["name"].asString(), gAgent.getID()); + + LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); + accountForUpdate(update); + + cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 + cat->setDescendentCount(0); + updateCategory(cat); + } + else + { + // bulk processing was faster than coroutine (coro request->processBulkUpdateInventory->coro response) + // category already exists, but needs an update + if (folderp->getVersion() != LLViewerInventoryCategory::VERSION_INITIAL + || folderp->getDescendentCount() != LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) + { + LL_WARNS() << "Inventory desync on folder creation. Newly created folder already has descendants or got a version.\n" + << "Name: " << folderp->getName() + << " Id: " << folderp->getUUID() + << " Version: " << folderp->getVersion() + << " Descendants: " << folderp->getDescendentCount() + << LL_ENDL; + } + // Recreate category with correct values + // Creating it anew just simplifies figuring out needed change-masks + // and making all needed updates, see updateCategory + LLPointer cat = new LLViewerInventoryCategory(categoryId, + result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(), + result["name"].asString(), gAgent.getID()); + + if (folderp->getParentUUID() != cat->getParentUUID()) + { + LL_WARNS() << "Inventory desync on folder creation. Newly created folder has wrong parent.\n" + << "Name: " << folderp->getName() + << " Id: " << folderp->getUUID() + << " Expected parent: " << cat->getParentUUID() + << " Actual parent: " << folderp->getParentUUID() + << LL_ENDL; + LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1); + accountForUpdate(update); + } + // else: Do not update parent, parent is already aware of the change. See processBulkUpdateInventory + + cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 + cat->setDescendentCount(0); + updateCategory(cat); + } if (callback) { -- cgit v1.2.3 From 357edecd9b938f2b83a6db0237c6343de7a18fcf Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 4 Aug 2020 15:30:20 +0300 Subject: SL-13669 Change inventory cache to use a standard LLSD format --- indra/newview/llinventorymodel.cpp | 114 ++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 59 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e7093eac02..c86a9a40d3 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -56,6 +56,7 @@ #include "llcallbacklist.h" #include "llvoavatarself.h" #include "llgesturemgr.h" +#include "llsdserialize.h" #include "llsdutil.h" #include "bufferarray.h" #include "bufferstream.h" @@ -76,8 +77,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; ///---------------------------------------------------------------------------- //BOOL decompress_file(const char* src_filename, const char* dst_filename); -static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv"; -static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv"; +static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv.llsd"; +static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv.llsd"; static const char * const LOG_INV("Inventory"); struct InventoryIDPtrLess @@ -2690,29 +2691,37 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, { if(filename.empty()) { - LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL; + LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL; return false; } - LL_INFOS(LOG_INV) << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL; - LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ - if(!file) + LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL; + + llifstream file(filename.c_str()); + + if (!file.is_open()) { LL_INFOS(LOG_INV) << "unable to load inventory from: " << filename << LL_ENDL; return false; } - // *NOTE: This buffer size is hard coded into scanf() below. - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - char keyword[MAX_STRING]; /*Flawfinder: ignore*/ - char value[MAX_STRING]; /*Flawfinder: ignore*/ - is_cache_obsolete = true; // Obsolete until proven current - while(!feof(file) && fgets(buffer, MAX_STRING, file)) + + is_cache_obsolete = true; // Obsolete until proven current + + std::string line; + LLPointer parser = new LLSDNotationParser(); + while (std::getline(file, line)) { - sscanf(buffer, " %126s %126s", keyword, value); /* Flawfinder: ignore */ - if(0 == strcmp("inv_cache_version", keyword)) + LLSD s_item; + std::istringstream iss(line); + if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) + { + LL_INFOS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL; + break; + } + + if (s_item.has("inv_cache_version")) { - S32 version; - int succ = sscanf(value,"%d",&version); - if ((1 == succ) && (version == sCurrentInvCacheVersion)) + S32 version = s_item["inv_cache_version"].asInteger(); + if (version == sCurrentInvCacheVersion) { // Cache is up to date is_cache_obsolete = false; @@ -2720,43 +2729,33 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } else { - // Cache is out of date + LL_INFOS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL; break; } } - else if(0 == strcmp("inv_category", keyword)) + else if (s_item.has("cat_id")) { if (is_cache_obsolete) break; - + LLPointer inv_cat = new LLViewerInventoryCategory(LLUUID::null); - if(inv_cat->importFileLocal(file)) + if(inv_cat->importLLSD(s_item)) { categories.push_back(inv_cat); } - else - { - LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL; - //delete inv_cat; // automatic when inv_cat is reassigned or destroyed - } } - else if(0 == strcmp("inv_item", keyword)) + else if (s_item.has("item_id")) { if (is_cache_obsolete) break; LLPointer inv_item = new LLViewerInventoryItem; - if( inv_item->importFileLocal(file) ) + if( inv_item->fromLLSD(s_item) ) { - // *FIX: Need a better solution, this prevents the - // application from freezing, but breaks inventory - // caching. if(inv_item->getUUID().isNull()) { - //delete inv_item; // automatic when inv_cat is reassigned or destroyed LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: " - << inv_item->getName() << LL_ENDL; - + << inv_item->getName() << LL_ENDL; } else { @@ -2769,44 +2768,40 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, items.push_back(inv_item); } } - } - else - { - LL_WARNS(LOG_INV) << "loadInventoryFromFile(). Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL; - //delete inv_item; // automatic when inv_cat is reassigned or destroyed - } - } - else - { - LL_WARNS(LOG_INV) << "Unknown token in inventory file '" << keyword << "'" - << LL_ENDL; + } } } - fclose(file); - if (is_cache_obsolete) - return false; - return true; + + file.close(); + + return !is_cache_obsolete; } // static bool LLInventoryModel::saveToFile(const std::string& filename, - const cat_array_t& categories, - const item_array_t& items) + const cat_array_t& categories, + const item_array_t& items) { - if(filename.empty()) + if (filename.empty()) { LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL; return false; } - LL_INFOS(LOG_INV) << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL; - LLFILE* file = LLFile::fopen(filename, "wb"); /*Flawfinder: ignore*/ - if(!file) + + LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL; + + llofstream fileXML(filename.c_str()); + if (!fileXML.is_open()) { LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL; return false; } - fprintf(file, "\tinv_cache_version\t%d\n",sCurrentInvCacheVersion); + LLSD cache_ver; + cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; + + fileXML << LLSDOStreamer(cache_ver) << std::endl; + S32 count = categories.size(); S32 i; for(i = 0; i < count; ++i) @@ -2814,17 +2809,18 @@ bool LLInventoryModel::saveToFile(const std::string& filename, LLViewerInventoryCategory* cat = categories[i]; if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) { - cat->exportFileLocal(file); + fileXML << LLSDOStreamer(cat->exportLLSD()) << std::endl; } } count = items.size(); for(i = 0; i < count; ++i) { - items[i]->exportFile(file); + fileXML << LLSDOStreamer(items[i]->asLLSD()) << std::endl; } - fclose(file); + fileXML.close(); + return true; } -- cgit v1.2.3 From bb5771fd3ec12ab17e589562448dcc6c15245aa4 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 20 Aug 2020 19:26:52 +0300 Subject: SL-13669 use warnings for inventory cache failures --- indra/newview/llinventorymodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c86a9a40d3..b37ebde4ec 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2714,7 +2714,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, std::istringstream iss(line); if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) { - LL_INFOS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL; + LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL; break; } @@ -2729,7 +2729,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } else { - LL_INFOS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL; + LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL; break; } } -- cgit v1.2.3 From 34444a08738d836274337253fadcc945d13b1fa5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 21 Sep 2020 23:47:08 +0300 Subject: SL-13697 Items I am wearing continue to go to lost and found Contribution from Ansariel Hiller --- indra/newview/llinventorymodel.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b37ebde4ec..543db806d4 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -946,16 +946,29 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) LLUUID new_parent_id = item->getParentUUID(); bool update_parent_on_server = false; - if (new_parent_id.isNull()) - { - // item with null parent will end in random location and then in Lost&Found, - // either move to default folder as if it is new item or don't move at all - LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() - << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName() - << ". New name: " << item->getName() - << "." << LL_ENDL; - new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - update_parent_on_server = true; + if (new_parent_id.isNull() && !LLApp::isExiting()) + { + if (old_parent_id.isNull()) + { + // Item with null parent will end in random location and then in Lost&Found, + // either move to default folder as if it is new item or don't move at all + LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() + << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName() + << ". New name: " << item->getName() + << "." << LL_ENDL; + new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + update_parent_on_server = true; + } + else + { + // Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point + LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() + << " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName() + << ". New name: " << item->getName() + << "." << LL_ENDL; + new_parent_id = old_parent_id; + update_parent_on_server = true; + } } if(old_parent_id != new_parent_id) -- cgit v1.2.3 From 738a651efaadb85ef4bec7a7995e9ee7b181949c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 23 Sep 2020 17:53:31 +0300 Subject: Fix line endings --- indra/newview/llinventorymodel.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 543db806d4..aad57b4e5b 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -958,16 +958,16 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) << "." << LL_ENDL; new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); update_parent_on_server = true; - } - else - { - // Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point - LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() - << " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName() - << ". New name: " << item->getName() - << "." << LL_ENDL; - new_parent_id = old_parent_id; - update_parent_on_server = true; + } + else + { + // Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point + LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID() + << " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName() + << ". New name: " << item->getName() + << "." << LL_ENDL; + new_parent_id = old_parent_id; + update_parent_on_server = true; } } -- cgit v1.2.3 From d9c779d59ce3c32e3dd64ac83b2869756a689747 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 12 Oct 2020 19:04:54 +0300 Subject: SL-14093 Show the amount of saved categories and items --- indra/newview/llinventorymodel.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventorymodel.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index aad57b4e5b..28db6a5808 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2816,6 +2816,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename, fileXML << LLSDOStreamer(cache_ver) << std::endl; S32 count = categories.size(); + S32 cat_count = 0; S32 i; for(i = 0; i < count; ++i) { @@ -2823,17 +2824,20 @@ bool LLInventoryModel::saveToFile(const std::string& filename, if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) { fileXML << LLSDOStreamer(cat->exportLLSD()) << std::endl; + cat_count++; } } - count = items.size(); - for(i = 0; i < count; ++i) + S32 it_count = items.size(); + for(i = 0; i < it_count; ++i) { fileXML << LLSDOStreamer(items[i]->asLLSD()) << std::endl; } fileXML.close(); + LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; + return true; } -- cgit v1.2.3