diff options
| -rw-r--r-- | indra/llcommon/llmd5.cpp | 37 | ||||
| -rw-r--r-- | indra/llcommon/llmd5.h | 11 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llcofwearables.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 24 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.h | 4 | ||||
| -rw-r--r-- | indra/newview/llinventoryobserver.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llinventoryobserver.h | 6 | ||||
| -rw-r--r-- | indra/newview/lloutfitobserver.cpp | 20 | ||||
| -rw-r--r-- | indra/newview/lloutfitobserver.h | 3 | ||||
| -rw-r--r-- | indra/newview/llpaneleditwearable.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llpaneloutfitedit.cpp | 3 | 
12 files changed, 110 insertions, 35 deletions
| diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index da9cb94e13..cc73c3e45c 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -171,11 +171,6 @@ void LLMD5::update(FILE* file){  } - - - - -  // MD5 update for istreams.  // Like update for files; see above. @@ -192,9 +187,10 @@ void LLMD5::update(std::istream& stream){  } - - - +void  LLMD5::update(const std::string& s) +{ +	update((unsigned char *)s.c_str(),s.length()); +}  // MD5 finalization. Ends an MD5 message-digest operation, writing the  // the message digest and zeroizing the context. @@ -277,7 +273,7 @@ LLMD5::LLMD5(const unsigned char *s)  	finalize();  } -void LLMD5::raw_digest(unsigned char *s) +void LLMD5::raw_digest(unsigned char *s) const  {  	if (!finalized)  	{ @@ -293,7 +289,7 @@ void LLMD5::raw_digest(unsigned char *s) -void LLMD5::hex_digest(char *s) +void LLMD5::hex_digest(char *s) const  {  	int i; @@ -319,6 +315,7 @@ void LLMD5::hex_digest(char *s) +  std::ostream& operator<<(std::ostream &stream, LLMD5 context)  {  	char s[33];		/* Flawfinder: ignore */ @@ -327,13 +324,25 @@ std::ostream& operator<<(std::ostream &stream, LLMD5 context)  	return stream;  } +bool operator==(const LLMD5& a, const LLMD5& b) +{ +	unsigned char a_guts[16]; +	unsigned char b_guts[16]; +	a.raw_digest(a_guts); +	b.raw_digest(b_guts); +	if (memcmp(a_guts,b_guts,16)==0) +		return true; +	else +		return false; +} - +bool operator!=(const LLMD5& a, const LLMD5& b) +{ +	return !(a==b); +}  // PRIVATE METHODS: - -  void LLMD5::init(){    finalized=0;  // we just started! @@ -531,3 +540,5 @@ void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){      output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |        (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);  } + + diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index df9d7324ab..4e68ba0d5e 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -95,6 +95,7 @@ public:    void  update     (const uint1 *input, const uint4 input_length);    void  update     (std::istream& stream);    void  update     (FILE *file); +  void  update     (const std::string& str);    void  finalize   ();  // constructors for special circumstances.  All these constructors finalize @@ -105,11 +106,10 @@ public:    LLMD5              (const unsigned char *string, const unsigned int number);  // methods to acquire finalized result -  void				raw_digest(unsigned char *array);	// provide 16-byte array for binary data -  void				hex_digest(char *string);			// provide 33-byte array for ascii-hex string -  friend std::ostream&   operator<< (std::ostream&, LLMD5 context); - +  void				raw_digest(unsigned char *array) const;	// provide 16-byte array for binary data +  void				hex_digest(char *string) const;			// provide 33-byte array for ascii-hex string +  friend std::ostream&   operator<< (std::ostream&, LLMD5 context);  private: @@ -131,4 +131,7 @@ private:  }; +LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); +LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b); +  #endif // LL_LLMD5_H diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a7d90ab8d3..d2449abf08 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2209,6 +2209,7 @@ void LLAppearanceMgr::updateIsDirty()  			LLViewerInventoryItem *item2 = outfit_items.get(i);  			if (item1->getLinkedUUID() != item2->getLinkedUUID() ||  +				item1->getName() != item2->getName() ||  				item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())  			{  				mOutfitIsDirty = true; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 86d9121213..f75ea23351 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -393,7 +393,8 @@ void LLCOFWearables::refresh()  		return;  	} -	if (mCOFVersion == catp->getVersion()) return; +	// BAP - removed check; does not detect item name changes. +	//if (mCOFVersion == catp->getVersion()) return;  	mCOFVersion = catp->getVersion();  	typedef std::vector<LLSD> values_vector_t; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 13e5cb516e..5a952bb6a8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -294,6 +294,30 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id,  	items = get_ptr_in_map(mParentChildItemTree, cat_id);  } +LLMD5 LLInventoryModel::hashDirectDescendentNames(const LLUUID& cat_id) const +{ +	LLInventoryModel::cat_array_t* cat_array; +	LLInventoryModel::item_array_t* item_array; +	getDirectDescendentsOf(cat_id,cat_array,item_array); +	LLMD5 item_name_hash; +	if (!item_array) +	{ +		item_name_hash.finalize(); +		return item_name_hash; +	} +	for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin(); +		 iter != item_array->end(); +		 iter++) +	{ +		const LLViewerInventoryItem *item = (*iter); +		if (!item) +			continue; +		item_name_hash.update(item->getName()); +	} +	item_name_hash.finalize(); +	return item_name_hash; +} +  // SJB: Added version to lock the arrays to catch potential logic bugs  void LLInventoryModel::lockDirectDescendentArrays(const LLUUID& cat_id,  												  cat_array_t*& categories, diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 7b56d0bdd1..ff8a5bae9b 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -41,6 +41,7 @@  #include "lluuid.h"  #include "llpermissionsflags.h"  #include "llstring.h" +#include "llmd5.h"  #include <map>  #include <set>  #include <string> @@ -194,6 +195,9 @@ public:  	void getDirectDescendentsOf(const LLUUID& cat_id,  								cat_array_t*& categories,  								item_array_t*& items) const; + +	// Compute a hash of direct descendent names (for detecting child name changes) +	LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const;  	// Starting with the object specified, add its descendents to the  	// array provided, but do not add the inventory object specified diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index bd6877d9d3..5416f01033 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -676,7 +676,9 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		 iter != mCategoryMap.end();  		 ++iter)  	{ -		LLViewerInventoryCategory* category = gInventory.getCategory((*iter).first); +		const LLUUID& cat_id = (*iter).first; + +		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);  		if (!category)  			continue; @@ -691,7 +693,7 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		// Check number of known descendents to find out whether it has changed.  		LLInventoryModel::cat_array_t* cats;  		LLInventoryModel::item_array_t* items; -		gInventory.getDirectDescendentsOf((*iter).first, cats, items); +		gInventory.getDirectDescendentsOf(cat_id, cats, items);  		if (!cats || !items)  		{  			llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl; @@ -703,20 +705,33 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  			continue;  		} - +		  		const S32 current_num_known_descendents = cats->count() + items->count();  		LLCategoryData cat_data = (*iter).second; +		bool cat_changed = false; +  		// If category version or descendents count has changed -		// update category data in mCategoryMap and fire a callback. +		// update category data in mCategoryMap  		if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount)  		{  			cat_data.mVersion = version;  			cat_data.mDescendentsCount = current_num_known_descendents; +			cat_changed = true; +		} -			cat_data.mCallback(); +		// If any item names have changed, update the name hash  +		LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cat_id); +		if (cat_data.mItemNameHash != item_name_hash) +		{ +			cat_data.mItemNameHash = item_name_hash; +			cat_changed = true;  		} + +		// If anything has changed above, fire the callback. +		if (cat_changed) +			cat_data.mCallback();  	}  } diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 4a88a65bf8..ccd5fa5f4e 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -34,6 +34,7 @@  #define LL_LLINVENTORYOBSERVERS_H  #include "lluuid.h" +#include "llmd5.h"  #include <string>  #include <vector> @@ -298,11 +299,14 @@ protected:  		: mCallback(cb)  		, mVersion(version)  		, mDescendentsCount(num_descendents) -		{} +		{ +			mItemNameHash.finalize(); +		}  		callback_t	mCallback;  		S32			mVersion;  		S32			mDescendentsCount; +		LLMD5		mItemNameHash;  	};  	typedef	std::map<LLUUID, LLCategoryData>	category_map_t; diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp index 03414b9964..60c941b456 100644 --- a/indra/newview/lloutfitobserver.cpp +++ b/indra/newview/lloutfitobserver.cpp @@ -40,6 +40,7 @@  LLOutfitObserver::LLOutfitObserver() :  	mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)  { +	mItemNameHash.finalize();  	gInventory.addObserver(this);  } @@ -87,13 +88,24 @@ bool LLOutfitObserver::checkCOF()  	if (cof.isNull())  		return false; +	bool cof_changed = false; +	LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof); +	if (item_name_hash != mItemNameHash) +	{ +		cof_changed = true; +		mItemNameHash = item_name_hash; +	} +  	S32 cof_version = getCategoryVersion(cof); +	if (cof_version != mCOFLastVersion) +	{ +		cof_changed = true; +		mCOFLastVersion = cof_version; +	} -	if (cof_version == mCOFLastVersion) +	if (!cof_changed)  		return false; - -	mCOFLastVersion = cof_version; - +	  	// dirtiness state should be updated before sending signal  	LLAppearanceMgr::getInstance()->updateIsDirty();  	mCOFChanged(); diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 3a66b5ea9f..4bb2b9b5ec 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -34,6 +34,7 @@  #define LL_OUTFITOBSERVER_H  #include "llsingleton.h" +#include "llmd5.h"  /**   * Outfit observer facade that provides simple possibility to subscribe on @@ -84,6 +85,8 @@ protected:  	bool mLastOutfitDirtiness; +	LLMD5 mItemNameHash; +  private:  	signal_t mBOFReplaced;  	signal_t mBOFChanged; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index f7e8a7b1a7..ddb5f49ab0 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -786,7 +786,7 @@ BOOL LLPanelEditWearable::isDirty() const  	if (mWearablePtr)  	{  		if (mWearablePtr->isDirty() || -			mWearablePtr->getName().compare(mNameEditor->getText()) != 0) +			mWearableItem->getName().compare(mNameEditor->getText()) != 0)  		{  			isDirty = TRUE;  		} @@ -987,7 +987,7 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)  		// the name of the wearable has changed, re-save wearable with new name  		LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);  		gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE); -		mNameEditor->setText(mWearablePtr->getName()); +		mNameEditor->setText(mWearableItem->getName());  	}  	else  	{ @@ -1004,7 +1004,7 @@ void LLPanelEditWearable::revertChanges()  	}  	mWearablePtr->revertValues(); -	mNameEditor->setText(mWearablePtr->getName()); +	mNameEditor->setText(mWearableItem->getName());  	updatePanelPickerControls(mWearablePtr->getType());  	updateTypeSpecificControls(mWearablePtr->getType());  	gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE); @@ -1050,7 +1050,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show)  		mDescTitle->setText(description_title);  		// set name -		mNameEditor->setText(wearable->getName()); +		mNameEditor->setText(mWearableItem->getName());  		updatePanelPickerControls(type);  		updateTypeSpecificControls(type); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 571261ff5b..767b01f039 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -1102,9 +1102,6 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)  void LLPanelOutfitEdit::onCOFChanged()  { -	//the panel is only updated when is visible to a user -	if (!isInVisibleChain()) return; -  	update();  } | 
