diff options
| author | Nyx Linden <nyx@lindenlab.com> | 2013-05-02 14:48:47 -0400 | 
|---|---|---|
| committer | Nyx Linden <nyx@lindenlab.com> | 2013-05-02 14:48:47 -0400 | 
| commit | e5d23969b9ad75ca535182ccbe76ff2b80d00605 (patch) | |
| tree | 3f7c27476a95da3a8a7eeffc228541a86a1eaaac /indra | |
| parent | af1431731802320e241037486b8bff0003a4d827 (diff) | |
| parent | 2f1f7c86bd7f366be5d5ccf64cf1af1300bc57a0 (diff) | |
merge
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llfile.cpp | 21 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 11 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llfloateravatarpicker.cpp | 9 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.cpp | 197 | ||||
| -rwxr-xr-x | indra/newview/llinventorymodel.h | 4 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/newview/llinventorymodelbackgroundfetch.cpp | 2 | ||||
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 29 | 
11 files changed, 290 insertions, 40 deletions
| diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index bc615ed39e..864b6e6975 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -853,7 +853,8 @@ llifstream::llifstream(const std::string& _Filename,  #if LL_WINDOWS  	std::istream(&_M_filebuf)  { -	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0) +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -872,7 +873,8 @@ llifstream::llifstream(const char* _Filename,  #if LL_WINDOWS  	std::istream(&_M_filebuf)  { -	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -917,8 +919,10 @@ bool llifstream::is_open() const  void llifstream::open(const char* _Filename, ios_base::openmode _Mode)  {	// open a C stream with specified mode -	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0) +  #if LL_WINDOWS +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -927,6 +931,7 @@ void llifstream::open(const char* _Filename, ios_base::openmode _Mode)  		_Myios::clear();  	}  #else +	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)  	{  		this->setstate(ios_base::failbit);  	} @@ -969,7 +974,8 @@ llofstream::llofstream(const std::string& _Filename,  #if LL_WINDOWS  	std::ostream(&_M_filebuf)  { -	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0) +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -988,7 +994,8 @@ llofstream::llofstream(const char* _Filename,  #if LL_WINDOWS  	std::ostream(&_M_filebuf)  { -	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0) +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -1032,8 +1039,9 @@ bool llofstream::is_open() const  void llofstream::open(const char* _Filename, ios_base::openmode _Mode)  {	// open a C stream with specified mode -	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)  #if LL_WINDOWS +	llutf16string wideName = utf8str_to_utf16str( _Filename ); +	if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)  	{  		_Myios::setstate(ios_base::failbit);  	} @@ -1042,6 +1050,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)  		_Myios::clear();  	}  #else +	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)  	{  		this->setstate(ios_base::failbit);  	} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 18a33b3542..1262089b3d 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14033,6 +14033,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>UseAISv3Inventory</key> +    <map> +      <key>Comment</key> +      <string>Allow use of AISv3 inventory - this setting should only be needed during development.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>ClickToWalk</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 399cea676c..40ec88f1be 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2890,7 +2890,7 @@ protected:  		}  		if (content["success"].asBoolean())  		{ -			LL_DEBUGS("Avatar") << dumpResponse() << LL_ENDL; +			//LL_DEBUGS("Avatar") << dumpResponse() << LL_ENDL;  			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))  			{  				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content); @@ -2907,7 +2907,8 @@ protected:  	{  		const LLSD& content = getContent();  		LL_WARNS("Avatar") << "appearance update request failed " -				<< dumpResponse() << LL_ENDL; +						   << dumpResponse() << LL_ENDL; +  		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))  		{  			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content); @@ -3247,6 +3248,13 @@ void show_created_outfit(LLUUID& folder_id, bool show_panel = true)  	LLAppearanceMgr::getInstance()->updateIsDirty();  	gAgentWearables.notifyLoadingFinished(); // New outfit is saved.  	LLAppearanceMgr::getInstance()->updatePanelOutfitName(""); + +	// For SSB, need to update appearance after we add a base outfit +	// link, since, the COF version has changed. There is a race +	// condition in initial outfit setup which can lead to rez +	// failures - SH-3860. +	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy; +	LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb);  }  LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel) @@ -3267,7 +3275,6 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b  	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,  																		 boost::bind(show_created_outfit,folder_id,show_panel));  	shallowCopyCategoryContents(getCOF(),folder_id, cb); -	createBaseOutfitLink(folder_id, cb);  	dumpCat(folder_id,"COF, new outfit"); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 08f08a0cb0..0844a70e25 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -819,7 +819,14 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()  			uuid_vec_t avatar_ids;  			std::vector<LLAvatarName> avatar_names;  			getSelectedAvatarData(list, avatar_ids, avatar_names); -			return mOkButtonValidateSignal(avatar_ids); +			if (avatar_ids.size() >= 1)  +			{ +				ret_val = mOkButtonValidateSignal(avatar_ids); +			} +			else +			{ +				ret_val = false; +			}  		}  	} diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index ae8efeecda..f60fd63eee 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -252,6 +252,23 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL  	return NULL;  } +bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const +{ +	LLInventoryObject *object = getObject(object_id); +	while (object && object->getParentUUID().notNull()) +	{ +		LLInventoryObject *parent_object = getObject(object->getParentUUID()); +		if (!parent_object) +		{ +			llwarns << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << llendl; +			return false; +		} +		object = parent_object; +	} +	result = object->getUUID(); +	return true; +} +  // Get the object by id. Returns NULL if not found.  LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const  { @@ -2083,7 +2100,7 @@ void LLInventoryModel::buildParentChildMap()  			// implement it, we would need a set or map of uuid pairs  			// which would be (folder_id, new_parent_id) to be sent up  			// to the server. -			llinfos << "Lost categroy: " << cat->getUUID() << " - " +			llinfos << "Lost category: " << cat->getUUID() << " - "  					<< cat->getName() << llendl;  			++lost;  			// plop it into the lost & found. @@ -2102,6 +2119,8 @@ void LLInventoryModel::buildParentChildMap()  				// it's a protected folder.  				cat->setParent(gInventory.getRootFolderID());  			} +			// FIXME note that updateServer() fails with protected +			// types, so this will not work as intended in that case.  			cat->updateServer(TRUE);  			catsp = getUnlockedCatArray(cat->getParentUUID());  			if(catsp) @@ -2247,6 +2266,11 @@ void LLInventoryModel::buildParentChildMap()  			notifyObservers();  		}  	} + +	//if (!gInventory.validate()) +	//{ +	//	llwarns << "model failed validity check!" << llendl; +	//}  }  struct LLUUIDAndName @@ -2917,6 +2941,9 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)  		InventoryCallbackInfo cbinfo = (*inv_it);  		gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID);  	} + +	//gInventory.validate(); +  	// Don't show the inventory.  We used to call showAgentInventory here.  	//LLFloaterInventory* view = LLFloaterInventory::getActiveInventory();  	//if(view) @@ -3363,6 +3390,174 @@ void LLInventoryModel::dumpInventory() const  	llinfos << "\n**********************\nEnd Inventory Dump" << llendl;  } +// Do various integrity checks on model, logging issues found and +// returning an overall good/bad flag. +bool LLInventoryModel::validate() const +{ +	bool valid = true; + +	if (getRootFolderID().isNull()) +	{ +		llwarns << "no root folder id" << llendl; +		valid = false; +	} +	if (getLibraryRootFolderID().isNull()) +	{ +		llwarns << "no root folder id" << llendl; +		valid = false; +	} + +	if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size()) +	{ +		// ParentChild should be one larger because of the special entry for null uuid. +		llinfos << "unexpected sizes: cat map size " << mCategoryMap.size() +				<< " parent/child " << mParentChildCategoryTree.size() << llendl; +		valid = false; +	} +	S32 cat_lock = 0; +	S32 item_lock = 0; +	S32 desc_unknown_count = 0; +	S32 version_unknown_count = 0; +	for(cat_map_t::const_iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit) +	{ +		const LLUUID& cat_id = cit->first; +		const LLViewerInventoryCategory *cat = cit->second; +		if (!cat) +		{ +			llwarns << "invalid cat" << llendl; +			valid = false; +			continue; +		} +		if (cat_id != cat->getUUID()) +		{ +			llwarns << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << llendl; +			valid = false; +		} + +		if (cat->getParentUUID().isNull()) +		{ +			if (cat_id != getRootFolderID() && cat_id != getLibraryRootFolderID()) +			{ +				llwarns << "cat " << cat_id << " has no parent, but is not root (" +						<< getRootFolderID() << ") or library root (" +						<< getLibraryRootFolderID() << ")" << llendl; +			} +		} +		cat_array_t* cats; +		item_array_t* items; +		getDirectDescendentsOf(cat_id,cats,items); +		if (!cats || !items) +		{ +			llwarns << "invalid direct descendents for " << cat_id << llendl; +			valid = false; +			continue; +		} +		if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) +		{ +			desc_unknown_count++; +		} +		else if (cats->size() + items->size() != cat->getDescendentCount()) +		{ +			llwarns << "invalid desc count for " << cat_id << " name " << cat->getName() +					<< " cached " << cat->getDescendentCount() +					<< " expected " << cats->size() << "+" << items->size() +					<< "=" << cats->size() +items->size() << llendl; +			valid = false; +		} +		if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) +		{ +			version_unknown_count++; +		} +		if (mCategoryLock.count(cat_id)) +		{ +			cat_lock++; +		} +		if (mItemLock.count(cat_id)) +		{ +			item_lock++; +		} +		for (S32 i = 0; i<items->size(); i++) +		{ +			LLViewerInventoryItem *item = items->get(i); + +			if (!item) +			{ +				llwarns << "null item at index " << i << " for cat " << cat_id << llendl; +				valid = false; +				continue; +			} + +			const LLUUID& item_id = item->getUUID(); +			 +			if (item->getParentUUID() != cat_id) +			{ +				llwarns << "wrong parent for " << item_id << " found " +						<< item->getParentUUID() << " expected " << cat_id +						<< llendl; +				valid = false; +			} + + +			// Entries in items and mItemMap should correspond. +			item_map_t::const_iterator it = mItemMap.find(item_id); +			if (it == mItemMap.end()) +			{ +				llwarns << "item " << item_id << " found as child of " +						<< cat_id << " but not in top level mItemMap" << llendl; +				valid = false; +			} +			else +			{ +				LLViewerInventoryItem *top_item = it->second; +				if (top_item != item) +				{ +					llwarns << "item mismatch, item_id " << item_id +							<< " top level entry is different, uuid " << top_item->getUUID() << llendl; +				} +			} + +			// Topmost ancestor should be root or library. +			LLUUID topmost_ancestor_id; +			bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); +			if (!found) +			{ +				llwarns << "unable to find topmost ancestor for " << item_id << llendl; +				valid = false; +			} +			else +			{ +				if (topmost_ancestor_id != getRootFolderID() && +					topmost_ancestor_id != getLibraryRootFolderID()) +				{ +					llwarns << "unrecognized top level ancestor for " << item_id +							<< " got " << topmost_ancestor_id +							<< " expected " << getRootFolderID() +							<< " or " << getLibraryRootFolderID() << llendl; +					valid = false; +				} +			} +		} + +	} +	if (cat_lock > 0 || item_lock > 0) +	{ +		llwarns << "Found locks on some categories: sub-cat arrays " +				<< cat_lock << ", item arrays " << item_lock << llendl; +	} +	if (desc_unknown_count != 0) +	{ +		llinfos << "Found " << desc_unknown_count << " cats with unknown descendent count" << llendl;  +	} +	if (version_unknown_count != 0) +	{ +		llinfos << "Found " << version_unknown_count << " cats with unknown version" << llendl; +	} + +	llinfos << "Validate done, valid = " << (U32) valid << llendl; + +	return valid; +} +  ///----------------------------------------------------------------------------  /// Local function definitions  ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index b7e1888f20..2459f10a37 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -227,6 +227,9 @@ public:  	// Check if one object has a parent chain up to the category specified by UUID.  	BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const; +	// Follow parent chain to the top. +	bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; +	  	//--------------------------------------------------------------------  	// Find  	//-------------------------------------------------------------------- @@ -551,6 +554,7 @@ private:  	//--------------------------------------------------------------------  public:  	void dumpInventory() const; +	bool validate() const;  /**                    Miscellaneous   **                                                                            ** diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 01b0e647a9..4eeb528c66 100644..100755 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -172,6 +172,8 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched()  		mRecursiveLibraryFetchStarted)  	{  		mAllFoldersFetched = TRUE; +		//llinfos << "All folders fetched, validating" << llendl; +		//gInventory.validate();  	}  	mFolderFetchActive = false;  } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 3eab85b8b3..f9afdee4f9 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1189,7 +1189,7 @@ void remove_inventory_item(  	if(obj)  	{  		std::string cap; -		if (gAgent.getRegion()) +		if (gAgent.getRegion() && gSavedSettings.getBOOL("UseAISv3Inventory"))  		{  			cap = gAgent.getRegion()->getCapability("InventoryAPIv3");  		} @@ -1267,7 +1267,7 @@ void remove_inventory_category(  		}  		std::string cap; -		if (gAgent.getRegion()) +		if (gAgent.getRegion() && gSavedSettings.getBOOL("UseAISv3Inventory"))  		{  			cap = gAgent.getRegion()->getCapability("InventoryAPIv3");  		} @@ -1409,7 +1409,7 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb)  		else  		{  			std::string cap; -			if (gAgent.getRegion()) +			if (gAgent.getRegion() && gSavedSettings.getBOOL("UseAISv3Inventory"))  			{  				cap = gAgent.getRegion()->getCapability("InventoryAPIv3");  			} diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index fcf5af76ff..670272e7be 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2697,24 +2697,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS  	if(ft && (0 == error_code) &&  	   (object = gObjectList.findObject(ft->mTaskID)))  	{ -		object->loadTaskInvFile(ft->mFilename); +		if (object->loadTaskInvFile(ft->mFilename)) +		{ -		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); -		LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); -		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; +			LLInventoryObject::object_list_t::iterator it = object->mInventory->begin(); +			LLInventoryObject::object_list_t::iterator end = object->mInventory->end(); +			std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs; -		for (; it != end && pending_lst.size(); ++it) -		{ -			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); -			if(item && item->getType() != LLAssetType::AT_CATEGORY) +			for (; it != end && pending_lst.size(); ++it)  			{ -				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); -				if (id_it != pending_lst.end()) +				LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get()); +				if(item && item->getType() != LLAssetType::AT_CATEGORY)  				{ -					pending_lst.erase(id_it); +					std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID()); +					if (id_it != pending_lst.end()) +					{ +						pending_lst.erase(id_it); +					}  				}  			}  		} +		else +		{ +			// MAINT-2597 - crash when trying to edit a no-mod object +			// Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?) +			// Stated repro was specific to no-mod objects so failing without user interaction should be safe. +			llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl; +		}  	}  	else  	{ @@ -2726,7 +2735,7 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS  	delete ft;  } -void LLViewerObject::loadTaskInvFile(const std::string& filename) +BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)  {  	std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);  	llifstream ifs(filename_and_local_path); @@ -2773,8 +2782,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)  	{  		llwarns << "unable to load task inventory: " << filename_and_local_path  				<< llendl; +		return FALSE;  	}  	doInventoryCallback(); + +	return TRUE;  }  void LLViewerObject::doInventoryCallback() diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 728d279c39..316dbce7d0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -656,7 +656,7 @@ protected:  	//  	static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status); -	void loadTaskInvFile(const std::string& filename); +	BOOL loadTaskInvFile(const std::string& filename);  	void doInventoryCallback();  	BOOL isOnMap(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 919627c47c..3189507b53 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -802,14 +802,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c  //------------------------------------------------------------------------  LLVOAvatar::~LLVOAvatar()  { -		if (!mFullyLoaded) -		{ +	if (!mFullyLoaded) +	{  		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); -		} -		else -		{ +	} +	else +	{  		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); -		} +	}  	logPendingPhases(); @@ -6059,6 +6059,11 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)  void LLVOAvatar::logPendingPhases()  { +	if (!isAgentAvatarValid()) +	{ +		return; +	} +	  	for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();  		 it != getPhases().end();  		 ++it) @@ -6093,6 +6098,11 @@ void LLVOAvatar::logPendingPhasesAllAvatars()  void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)  { +	if (!isAgentAvatarValid()) +	{ +		return; +	} +	  	LLSD record;  	record["timer_name"] = phase_name;  	record["avatar_id"] = getID(); @@ -6109,13 +6119,6 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());  	record["is_self"] = isSelf(); - -#if 0 // verbose logging -	std::ostringstream ostr; -	ostr << LLSDNotationStreamer(record); -	LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl; -#endif -  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->addMetricsTimerRecord(record); | 
