diff options
69 files changed, 1415 insertions, 662 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index bbdfaf655d..ed470c7ae8 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1352,7 +1352,8 @@ Sovereign Engineer      MAINT-7343      SL-11079      OPEN-343 -	SL-11625 +    SL-11625 +    BUG-229030  SpacedOut Frye  	VWR-34  	VWR-45 diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index a5770c5528..6cd3cd9278 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -61,7 +61,7 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)    set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries")  endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake)  set(TEMPLATE_VERIFIER_OPTIONS "" CACHE STRING "Options for scripts/template_verifier.py") -set(TEMPLATE_VERIFIER_MASTER_URL "http://bitbucket.org/lindenlab/master-message-template/raw/tip/message_template.msg" CACHE STRING "Location of the master message template") +set(TEMPLATE_VERIFIER_MASTER_URL "https://bitbucket.org/lindenlab/master-message-template-git/raw/master/message_template.msg" CACHE STRING "Location of the master message template")  if (NOT CMAKE_BUILD_TYPE)    set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp index af8394b60c..fb0d12f0af 100644 --- a/indra/llappearance/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -70,7 +70,7 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)  	static LLStdStringHandle wearable_string = LLXmlTree::addAttributeString("wearable");  	if( node->getFastAttributeString( wearable_string, wearable) )  	{ -		mWearableType = LLWearableType::typeNameToType( wearable ); +		mWearableType = LLWearableType::getInstance()->typeNameToType( wearable );  	}  	static LLStdStringHandle edit_group_string = LLXmlTree::addAttributeString("edit_group"); diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index 28a36e6e41..e4bc8ff427 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -73,17 +73,17 @@ LLWearable::~LLWearable()  const std::string& LLWearable::getTypeLabel() const  { -	return LLWearableType::getTypeLabel(mType); +	return LLWearableType::getInstance()->getTypeLabel(mType);  }  const std::string& LLWearable::getTypeName() const  { -	return LLWearableType::getTypeName(mType); +	return LLWearableType::getInstance()->getTypeName(mType);  }  LLAssetType::EType LLWearable::getAssetType() const  { -	return LLWearableType::getAssetType(mType); +	return LLWearableType::getInstance()->getAssetType(mType);  }  BOOL LLWearable::exportFile(const std::string& filename) const diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp index 66cc4f3766..0eaeedb6ee 100644 --- a/indra/llappearance/llwearabledata.cpp +++ b/indra/llappearance/llwearabledata.cpp @@ -231,10 +231,11 @@ BOOL LLWearableData::getWearableIndex(const LLWearable *wearable, U32& index_fou  U32 LLWearableData::getClothingLayerCount() const  {  	U32 count = 0; +    LLWearableType *wr_inst = LLWearableType::getInstance();  	for (S32 i = 0; i < LLWearableType::WT_COUNT; i++)  	{  		LLWearableType::EType type = (LLWearableType::EType)i; -		if (LLWearableType::getAssetType(type)==LLAssetType::AT_CLOTHING) +		if (wr_inst->getAssetType(type)==LLAssetType::AT_CLOTHING)  		{  			count += getWearableCount(type);  		} @@ -244,7 +245,7 @@ U32 LLWearableData::getClothingLayerCount() const  BOOL LLWearableData::canAddWearable(const LLWearableType::EType type) const  { -	LLAssetType::EType a_type = LLWearableType::getAssetType(type); +    LLAssetType::EType a_type = LLWearableType::getInstance()->getAssetType(type);  	if (a_type==LLAssetType::AT_CLOTHING)  	{  		return (getClothingLayerCount() < MAX_CLOTHING_LAYERS); diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index 281060d01d..4ac611b1de 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -30,153 +30,98 @@  #include "llinventorydefines.h" -struct WearableEntry : public LLDictionaryEntry +LLWearableType::LLWearableDictionary::LLWearableDictionary(LLTranslationBridge::ptr_t& trans)  { -	WearableEntry(LLWearableType& wtype, -				  const std::string &name, -				  const std::string& default_new_name, -				  LLAssetType::EType assetType, -				  LLInventoryType::EIconName iconName, -				  BOOL disable_camera_switch = FALSE, -				  BOOL allow_multiwear = TRUE) : -		LLDictionaryEntry(name), -		mAssetType(assetType), -		mDefaultNewName(default_new_name), -		mLabel(wtype.mTrans->getString(name)), -		mIconName(iconName), -		mDisableCameraSwitch(disable_camera_switch), -		mAllowMultiwear(allow_multiwear) -	{ -		 -	} -	const LLAssetType::EType mAssetType; -	const std::string mLabel; -	const std::string mDefaultNewName; //keep mLabel for backward compatibility -	LLInventoryType::EIconName mIconName; -	BOOL mDisableCameraSwitch; -	BOOL mAllowMultiwear; -}; - -class LLWearableDictionary : public LLParamSingleton<LLWearableDictionary>, -							 public LLDictionary<LLWearableType::EType, WearableEntry> -{ -	LLSINGLETON(LLWearableDictionary, LLWearableType&); -}; - -LLWearableDictionary::LLWearableDictionary(LLWearableType& wtype) -{ -	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry(wtype, "shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE)); -	addEntry(LLWearableType::WT_SKIN,         new WearableEntry(wtype, "skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE)); -	addEntry(LLWearableType::WT_HAIR,         new WearableEntry(wtype, "hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE)); -	addEntry(LLWearableType::WT_EYES,         new WearableEntry(wtype, "eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE)); -	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry(wtype, "shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE)); -	addEntry(LLWearableType::WT_PANTS,        new WearableEntry(wtype, "pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE)); -	addEntry(LLWearableType::WT_SHOES,        new WearableEntry(wtype, "shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE)); -	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry(wtype, "socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE)); -	addEntry(LLWearableType::WT_JACKET,       new WearableEntry(wtype, "jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE)); -	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry(wtype, "gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE)); -	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry(wtype, "undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE)); -	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry(wtype, "underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE)); -	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry(wtype, "skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE)); -	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry(wtype, "alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); -	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry(wtype, "tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); -	addEntry(LLWearableType::WT_UNIVERSAL,    new WearableEntry(wtype, "universal",   "New Universal",     LLAssetType::AT_CLOTHING,   LLInventoryType::ICONNAME_CLOTHING_UNIVERSAL, FALSE, TRUE)); - -	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry(wtype, "physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); - -	addEntry(LLWearableType::WT_INVALID,      new WearableEntry(wtype, "invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_UNKNOWN, FALSE, FALSE)); -	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry(wtype, "none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE)); +	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry(trans, "shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE)); +	addEntry(LLWearableType::WT_SKIN,         new WearableEntry(trans, "skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE)); +	addEntry(LLWearableType::WT_HAIR,         new WearableEntry(trans, "hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE)); +	addEntry(LLWearableType::WT_EYES,         new WearableEntry(trans, "eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE)); +	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry(trans, "shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE)); +	addEntry(LLWearableType::WT_PANTS,        new WearableEntry(trans, "pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE)); +	addEntry(LLWearableType::WT_SHOES,        new WearableEntry(trans, "shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE)); +	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry(trans, "socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE)); +	addEntry(LLWearableType::WT_JACKET,       new WearableEntry(trans, "jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE)); +	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry(trans, "gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE)); +	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry(trans, "undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE)); +	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry(trans, "underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE)); +	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry(trans, "skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE)); +	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry(trans, "alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); +	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry(trans, "tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); +	addEntry(LLWearableType::WT_UNIVERSAL,    new WearableEntry(trans, "universal",   "New Universal",     LLAssetType::AT_CLOTHING,   LLInventoryType::ICONNAME_CLOTHING_UNIVERSAL, FALSE, TRUE)); + +	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry(trans, "physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); + +	addEntry(LLWearableType::WT_INVALID,      new WearableEntry(trans, "invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_UNKNOWN, FALSE, FALSE)); +	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry(trans, "none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));  }  // class LLWearableType -LLWearableType::LLWearableType(LLTranslationBridge* trans) +LLWearableType::LLWearableType(LLTranslationBridge::ptr_t &trans) +:   mDictionary(trans)  { -    // LLTranslationBridge exists, but is not ready at this point in time since strings.xml is not yet loaded -    mTrans = trans;  }  LLWearableType::~LLWearableType()  { -    delete mTrans;  }  void LLWearableType::initSingleton()  { -    // To make sure all wrapping functions will crash without initing LLWearableType; -    LLWearableDictionary::initParamSingleton(*this); - -    // Todo: consider merging LLWearableType and LLWearableDictionary  } -// static  LLWearableType::EType LLWearableType::typeNameToType(const std::string& type_name)  { -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const LLWearableType::EType wearable = dict->lookup(type_name); +	const LLWearableType::EType wearable = mDictionary.lookup(type_name);  	return wearable;  } -// static   const std::string& LLWearableType::getTypeName(LLWearableType::EType type)  {  -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return getTypeName(WT_INVALID);  	return entry->mName;  } -//static   const std::string& LLWearableType::getTypeDefaultNewName(LLWearableType::EType type)  {  -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return getTypeDefaultNewName(WT_INVALID);  	return entry->mDefaultNewName;  } -// static   const std::string& LLWearableType::getTypeLabel(LLWearableType::EType type)  {  -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return getTypeLabel(WT_INVALID);  	return entry->mLabel;  } -// static   LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)  { -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return getAssetType(WT_INVALID);  	return entry->mAssetType;  } -// static   LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type)  { -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return getIconName(WT_INVALID);  	return entry->mIconName;  }  -// static   BOOL LLWearableType::getDisableCameraSwitch(LLWearableType::EType type)  { -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return FALSE;  	return entry->mDisableCameraSwitch;  } -// static  BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)  { -	const LLWearableDictionary *dict = LLWearableDictionary::getInstance(); -	const WearableEntry *entry = dict->lookup(type); +	const WearableEntry *entry = mDictionary.lookup(type);  	if (!entry) return FALSE;  	return entry->mAllowMultiwear;  } diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h index 57f3ef160d..793a33cc87 100644 --- a/indra/llappearance/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -35,10 +35,9 @@  class LLWearableType : public LLParamSingleton<LLWearableType>  { -	LLSINGLETON(LLWearableType, LLTranslationBridge* trans); +	LLSINGLETON(LLWearableType, LLTranslationBridge::ptr_t &trans);  	~LLWearableType();  	void initSingleton(); -	friend struct WearableEntry;  public:   	enum EType  	{ @@ -67,20 +66,53 @@ public:  	// Most methods are wrappers for dictionary, but if LLWearableType is not initialized,  	// they will crash. Whole LLWearableType is just wrapper for convinient calls. -	static const std::string& 			getTypeName(EType type); -	static const std::string& 			getTypeDefaultNewName(EType type); -	static const std::string& 			getTypeLabel(EType type); -	static LLAssetType::EType 			getAssetType(EType type); -	static EType 						typeNameToType(const std::string& type_name); -	static LLInventoryType::EIconName 	getIconName(EType type); -	static BOOL 						getDisableCameraSwitch(EType type); -	static BOOL 						getAllowMultiwear(EType type); +	const std::string& 					getTypeName(EType type); +	const std::string& 					getTypeDefaultNewName(EType type); +	const std::string& 					getTypeLabel(EType type); +	LLAssetType::EType 					getAssetType(EType type); +	EType 								typeNameToType(const std::string& type_name); +	LLInventoryType::EIconName 			getIconName(EType type); +	BOOL 								getDisableCameraSwitch(EType type); +	BOOL 								getAllowMultiwear(EType type);  	static EType						inventoryFlagsToWearableType(U32 flags); -protected: +private: +    struct WearableEntry : public LLDictionaryEntry +    { +        WearableEntry(LLTranslationBridge::ptr_t& trans, +            const std::string &name, +            const std::string& default_new_name, +            LLAssetType::EType assetType, +            LLInventoryType::EIconName iconName, +            BOOL disable_camera_switch = FALSE, +            BOOL allow_multiwear = TRUE) : +            LLDictionaryEntry(name), +            mAssetType(assetType), +            mDefaultNewName(default_new_name), +            mLabel(trans->getString(name)), +            mIconName(iconName), +            mDisableCameraSwitch(disable_camera_switch), +            mAllowMultiwear(allow_multiwear) +        { -	LLTranslationBridge* mTrans; +        } +        const LLAssetType::EType mAssetType; +        const std::string mLabel; +        const std::string mDefaultNewName; +        LLInventoryType::EIconName mIconName; +        BOOL mDisableCameraSwitch; +        BOOL mAllowMultiwear; +    }; + +    class LLWearableDictionary : public LLDictionary<LLWearableType::EType, WearableEntry> +    { +    public: +        LLWearableDictionary(LLTranslationBridge::ptr_t& trans); +        ~LLWearableDictionary() {} +    }; + +    LLWearableDictionary mDictionary;  };  #endif  // LL_LLWEARABLETYPE_H diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f876b8ee4a..012ec08f07 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -435,6 +435,62 @@ namespace  	typedef std::vector<LLError::RecorderPtr> Recorders;  	typedef std::vector<LLError::CallSite*> CallSiteVector; +    class SettingsConfig : public LLRefCount +    { +        friend class Globals; + +    public: +        virtual ~SettingsConfig(); + +        LLError::ELevel                     mDefaultLevel; + +        bool 								mLogAlwaysFlush; + +        U32 								mEnabledLogTypesMask; + +        LevelMap                            mFunctionLevelMap; +        LevelMap                            mClassLevelMap; +        LevelMap                            mFileLevelMap; +        LevelMap                            mTagLevelMap; +        std::map<std::string, unsigned int> mUniqueLogMessages; + +        LLError::FatalFunction              mCrashFunction; +        LLError::TimeFunction               mTimeFunction; + +        Recorders                           mRecorders; +        LLMutex                             mRecorderMutex; + +        int                                 mShouldLogCallCounter; + +    private: +        SettingsConfig(); +    }; + +    typedef LLPointer<SettingsConfig> SettingsConfigPtr; + +    SettingsConfig::SettingsConfig() +        : LLRefCount(), +        mDefaultLevel(LLError::LEVEL_DEBUG), +        mLogAlwaysFlush(true), +        mEnabledLogTypesMask(255), +        mFunctionLevelMap(), +        mClassLevelMap(), +        mFileLevelMap(), +        mTagLevelMap(), +        mUniqueLogMessages(), +        mCrashFunction(NULL), +        mTimeFunction(NULL), +        mRecorders(), +        mRecorderMutex(), +        mShouldLogCallCounter(0) +    { +    } + +    SettingsConfig::~SettingsConfig() +    { +        mRecorders.clear(); +    } +  	class Globals  	{      public: @@ -449,14 +505,21 @@ namespace  		void addCallSite(LLError::CallSite&);  		void invalidateCallSites(); +        SettingsConfigPtr getSettingsConfig(); + +        void resetSettingsConfig(); +        LLError::SettingsStoragePtr saveAndResetSettingsConfig(); +        void restore(LLError::SettingsStoragePtr pSettingsStorage);  	private:  		CallSiteVector callSites; +        SettingsConfigPtr mSettingsConfig;  	};  	Globals::Globals()  		: messageStream(),  		messageStreamInUse(false), -		callSites() +		callSites(), +        mSettingsConfig(new SettingsConfig())  	{  	} @@ -486,120 +549,31 @@ namespace  		callSites.clear();  	} -} - -namespace LLError -{ -	class SettingsConfig : public LLRefCount -	{ -		friend class Settings; - -	public: -		virtual ~SettingsConfig(); - -		LLError::ELevel                     mDefaultLevel; - -        bool 								mLogAlwaysFlush; - -        U32 								mEnabledLogTypesMask; - -		LevelMap                            mFunctionLevelMap; -		LevelMap                            mClassLevelMap; -		LevelMap                            mFileLevelMap; -		LevelMap                            mTagLevelMap; -		std::map<std::string, unsigned int> mUniqueLogMessages; -		 -		LLError::FatalFunction              mCrashFunction; -		LLError::TimeFunction               mTimeFunction; - -		Recorders                           mRecorders; - -		int                                 mShouldLogCallCounter; - -	private: -		SettingsConfig(); -	}; - -	typedef LLPointer<SettingsConfig> SettingsConfigPtr; - -	class Settings -	{ -    public: -        static Settings* getInstance(); -    protected: -		Settings(); -	public: -		SettingsConfigPtr getSettingsConfig(); - -		void reset(); -		SettingsStoragePtr saveAndReset();  -		void restore(SettingsStoragePtr pSettingsStorage); -		 -	private: -		SettingsConfigPtr mSettingsConfig; -	}; - -	SettingsConfig::SettingsConfig() -		: LLRefCount(), -		mDefaultLevel(LLError::LEVEL_DEBUG), -		mLogAlwaysFlush(true), -		mEnabledLogTypesMask(255), -		mFunctionLevelMap(), -		mClassLevelMap(), -		mFileLevelMap(), -		mTagLevelMap(), -		mUniqueLogMessages(), -		mCrashFunction(NULL), -		mTimeFunction(NULL), -		mRecorders(), -		mShouldLogCallCounter(0) -	{ -	} - -	SettingsConfig::~SettingsConfig() -	{ -		mRecorders.clear(); -	} - -	Settings::Settings(): -		mSettingsConfig(new SettingsConfig()) -	{ -	} -    Settings* Settings::getInstance() +    SettingsConfigPtr Globals::getSettingsConfig()      { -        // According to C++11 Function-Local Initialization -        // of static variables is supposed to be thread safe -        // without risk of deadlocks. -        static Settings inst; - -        return &inst; +        return mSettingsConfig;      } -	SettingsConfigPtr Settings::getSettingsConfig() -	{ -		return mSettingsConfig; -	} - -	void Settings::reset() -	{ -		Globals::getInstance()->invalidateCallSites(); -		mSettingsConfig = new SettingsConfig(); -	} +    void Globals::resetSettingsConfig() +    { +        invalidateCallSites(); +        mSettingsConfig = new SettingsConfig(); +    } -	SettingsStoragePtr Settings::saveAndReset() -	{ -		SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); -		reset(); -		return oldSettingsConfig; -	} +    LLError::SettingsStoragePtr Globals::saveAndResetSettingsConfig() +    { +        LLError::SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); +        resetSettingsConfig(); +        return oldSettingsConfig; +    } -	void Settings::restore(SettingsStoragePtr pSettingsStorage) -	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get())); -		mSettingsConfig = newSettingsConfig; -	} +    void Globals::restore(LLError::SettingsStoragePtr pSettingsStorage) +    { +        invalidateCallSites(); +        SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get())); +        mSettingsConfig = newSettingsConfig; +    }  }  namespace LLError @@ -723,7 +697,7 @@ namespace  	void commonInit(const std::string& user_dir, const std::string& app_dir, bool log_to_stderr = true)  	{ -		LLError::Settings::getInstance()->reset(); +		Globals::getInstance()->resetSettingsConfig();  		LLError::setDefaultLevel(LLError::LEVEL_INFO);  		LLError::setAlwaysFlush(true); @@ -765,13 +739,13 @@ namespace LLError  	void setFatalFunction(const FatalFunction& f)  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		s->mCrashFunction = f;  	}  	FatalFunction getFatalFunction()  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		return s->mCrashFunction;  	} @@ -782,72 +756,77 @@ namespace LLError  	void setTimeFunction(TimeFunction f)  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		s->mTimeFunction = f;  	}  	void setDefaultLevel(ELevel level)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mDefaultLevel = level;  	}  	ELevel getDefaultLevel()  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		return s->mDefaultLevel;  	}  	void setAlwaysFlush(bool flush)  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		s->mLogAlwaysFlush = flush;  	}  	bool getAlwaysFlush()  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		return s->mLogAlwaysFlush;  	}  	void setEnabledLogTypesMask(U32 mask)  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		s->mEnabledLogTypesMask = mask;  	}  	U32 getEnabledLogTypesMask()  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		return s->mEnabledLogTypesMask;  	}  	void setFunctionLevel(const std::string& function_name, ELevel level)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mFunctionLevelMap[function_name] = level;  	}  	void setClassLevel(const std::string& class_name, ELevel level)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mClassLevelMap[class_name] = level;  	}  	void setFileLevel(const std::string& file_name, ELevel level)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mFileLevelMap[file_name] = level;  	}  	void setTagLevel(const std::string& tag_name, ELevel level)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mTagLevelMap[tag_name] = level;  	} @@ -892,8 +871,9 @@ namespace LLError  {  	void configure(const LLSD& config)  	{ -		Globals::getInstance()->invalidateCallSites(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		g->invalidateCallSites(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mFunctionLevelMap.clear();  		s->mClassLevelMap.clear(); @@ -1020,7 +1000,8 @@ namespace LLError  		{  			return;  		} -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); +		LLMutexLock lock(&s->mRecorderMutex);  		s->mRecorders.push_back(recorder);  	} @@ -1030,7 +1011,8 @@ namespace LLError  		{  			return;  		} -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); +		LLMutexLock lock(&s->mRecorderMutex);  		s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder),  							s->mRecorders.end());  	} @@ -1042,11 +1024,12 @@ namespace LLError      // with a Recorders::iterator indicating the position of that entry in      // mRecorders. The shared_ptr might be empty (operator!() returns true) if      // there was no such RECORDER subclass instance in mRecorders. +    // +    // NOTE!!! Requires external mutex lock!!!      template <typename RECORDER>      std::pair<boost::shared_ptr<RECORDER>, Recorders::iterator> -    findRecorderPos() +    findRecorderPos(SettingsConfigPtr &s)      { -        SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();          // Since we promise to return an iterator, use a classic iterator          // loop.          auto end{s->mRecorders.end()}; @@ -1077,7 +1060,9 @@ namespace LLError      template <typename RECORDER>      boost::shared_ptr<RECORDER> findRecorder()      { -        return findRecorderPos<RECORDER>().first; +        SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); +        LLMutexLock lock(&s->mRecorderMutex); +        return findRecorderPos<RECORDER>(s).first;      }      // Remove an entry from SettingsConfig::mRecorders whose RecorderPtr @@ -1086,10 +1071,11 @@ namespace LLError      template <typename RECORDER>      bool removeRecorder()      { -        auto found = findRecorderPos<RECORDER>(); +        SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig(); +        LLMutexLock lock(&s->mRecorderMutex); +        auto found = findRecorderPos<RECORDER>(s);          if (found.first)          { -            SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();              s->mRecorders.erase(found.second);          }          return bool(found.first); @@ -1187,10 +1173,11 @@ namespace  	void writeToRecorders(const LLError::CallSite& site, const std::string& message)  	{  		LLError::ELevel level = site.mLevel; -		LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();          std::string escaped_message; -         + +        LLMutexLock lock(&s->mRecorderMutex);  		for (Recorders::const_iterator i = s->mRecorders.begin();  			i != s->mRecorders.end();  			++i) @@ -1325,7 +1312,8 @@ namespace LLError  			return false;  		} -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		Globals *g = Globals::getInstance(); +		SettingsConfigPtr s = g->getSettingsConfig();  		s->mShouldLogCallCounter++; @@ -1355,7 +1343,7 @@ namespace LLError  			: false);  		site.mCached = true; -		Globals::getInstance()->addCallSite(site); +		g->addCallSite(site);  		return site.mShouldLog = site.mLevel >= compareLevel;  	} @@ -1419,7 +1407,7 @@ namespace LLError  		}  		Globals* g = Globals::getInstance(); -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = g->getSettingsConfig();  		std::string message = out->str();  		if (out == &g->messageStream) @@ -1478,12 +1466,12 @@ namespace LLError  {  	SettingsStoragePtr saveAndResetSettings()  	{ -		return Settings::getInstance()->saveAndReset(); +		return Globals::getInstance()->saveAndResetSettingsConfig();  	}  	void restoreSettings(SettingsStoragePtr pSettingsStorage)  	{ -		return Settings::getInstance()->restore(pSettingsStorage); +		return Globals::getInstance()->restore(pSettingsStorage);  	}  	std::string removePrefix(std::string& s, const std::string& p) @@ -1529,7 +1517,7 @@ namespace LLError  	int shouldLogCallCount()  	{ -		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();  		return s->mShouldLogCallCounter;  	} @@ -1707,8 +1695,8 @@ bool debugLoggingEnabled(const std::string& tag)      {          return false;      } -         -    LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); + +    SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();      LLError::ELevel level = LLError::LEVEL_DEBUG;      bool res = checkLevelMap(s->mTagLevelMap, tag, level);      return res; diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index 6cf6af6437..96c1297e0d 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -173,6 +173,71 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,  	return ok;  } +BOOL LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) +{ +    for (S32 idx = 0; idx < count; ++idx) +    { +        if (!unpackU16(values[idx], name)) +        { +            LL_WARNS("DATAPACKER") << "Buffer overflow reading Unsigned 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL; +            return FALSE; +        } +    } +    return TRUE; +} + +BOOL LLDataPacker::unpackS16s(S16 *values, S32 count, const char *name) +{ +    for (S32 idx = 0; idx < count; ++idx) +    { +        if (!unpackS16(values[idx], name)) +        { +            LL_WARNS("DATAPACKER") << "Buffer overflow reading Signed 16s \"" << name << "\" at index " << idx << "!" << LL_ENDL; +            return FALSE; +        } +    } +    return TRUE; +} + +BOOL LLDataPacker::unpackF32s(F32 *values, S32 count, const char *name) +{ +    for (S32 idx = 0; idx < count; ++idx) +    { +        if (!unpackF32(values[idx], name)) +        { +            LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL; +            return FALSE; +        } +    } +    return TRUE; +} + +BOOL LLDataPacker::unpackColor4Us(LLColor4U *values, S32 count, const char *name) +{ +    for (S32 idx = 0; idx < count; ++idx) +    { +        if (!unpackColor4U(values[idx], name)) +        { +            LL_WARNS("DATAPACKER") << "Buffer overflow reading Float 32s \"" << name << "\" at index " << idx << "!" << LL_ENDL; +            return FALSE; +        } +    } +    return TRUE; +} + +BOOL LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) +{ +    for (S32 idx = 0; idx < count; ++idx) +    { +        if (!unpackUUID(values[idx], name)) +        { +            LL_WARNS("DATAPACKER") << "Buffer overflow reading UUIDs \"" << name << "\" at index " << idx << "!" << LL_ENDL; +            return FALSE; +        } +    } +    return TRUE; +} +  //---------------------------------------------------------------------------  // LLDataPackerBinaryBuffer implementation  //--------------------------------------------------------------------------- @@ -319,6 +384,29 @@ BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name)  	return success;  } +BOOL LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) +{ +    BOOL success = verifyLength(sizeof(S16), name); + +    if (mWriteEnabled && success) +    { +        htolememcpy(mCurBufferp, &value, MVT_S16, 2); +    } +    mCurBufferp += 2; +    return success; +} + +BOOL LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) +{ +    BOOL success = verifyLength(sizeof(S16), name); + +    if (success) +    { +        htolememcpy(&value, mCurBufferp, MVT_S16, 2); +    } +    mCurBufferp += 2; +    return success; +}  BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name)  { @@ -884,6 +972,52 @@ BOOL LLDataPackerAsciiBuffer::unpackU16(U16 &value, const char *name)  	return success;  } +BOOL LLDataPackerAsciiBuffer::packS16(const S16 value, const char *name) +{ +    BOOL success = TRUE; +    writeIndentedName(name); +    int numCopied = 0; +    if (mWriteEnabled) +    { +        numCopied = snprintf(mCurBufferp, getBufferSize() - getCurrentSize(), "%d\n", value); /* Flawfinder: ignore */ +    } +    else +    { +        numCopied = snprintf(DUMMY_BUFFER, sizeof(DUMMY_BUFFER), "%d\n", value); /* Flawfinder: ignore */ +    } + +    // snprintf returns number of bytes that would have been written +    // had the output not being truncated. In that case, it will +    // return either -1 or value >= passed in size value . So a check needs to be added +    // to detect truncation, and if there is any, only account for the +    // actual number of bytes written..and not what could have been +    // written. +    if(numCopied < 0 || numCopied > getBufferSize() - getCurrentSize()) +    { +        numCopied = getBufferSize() - getCurrentSize(); +        LL_WARNS() << "LLDataPackerAsciiBuffer::packS16: val truncated: " << LL_ENDL; +    } + +    mCurBufferp += numCopied; + +    return success; +} + + +BOOL LLDataPackerAsciiBuffer::unpackS16(S16 &value, const char *name) +{ +    BOOL success = TRUE; +    char valuestr[DP_BUFSIZE]; /* Flawfinder: ignore */ +    if (!getValueStr(name, valuestr, DP_BUFSIZE)) +    { +        return FALSE; +    } + +    S32 in_val; +    sscanf(valuestr, "%d", &in_val); +    value = in_val; +    return success; +}  BOOL LLDataPackerAsciiBuffer::packU32(const U32 value, const char *name)  { @@ -1587,6 +1721,36 @@ BOOL LLDataPackerAsciiFile::unpackU16(U16 &value, const char *name)  	return success;  } +BOOL LLDataPackerAsciiFile::packS16(const S16 value, const char *name) +{ +    BOOL success = TRUE; +    writeIndentedName(name); +    if (mFP) +    { +        fprintf(mFP, "%d\n", value);	 +    } +    else if (mOutputStream) +    { +        *mOutputStream << "" << value << "\n"; +    } +    return success; +} + + +BOOL LLDataPackerAsciiFile::unpackS16(S16 &value, const char *name) +{ +    BOOL success = TRUE; +    char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore */ +    if (!getValueStr(name, valuestr, DP_BUFSIZE)) +    { +        return FALSE; +    } + +    S32 in_val; +    sscanf(valuestr, "%d", &in_val); +    value = in_val; +    return success; +}  BOOL LLDataPackerAsciiFile::packU32(const U32 value, const char *name)  { diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h index 5140f56c01..ac28cadbce 100644 --- a/indra/llmessage/lldatapacker.h +++ b/indra/llmessage/lldatapacker.h @@ -60,6 +60,11 @@ public:  	virtual BOOL		packU16(const U16 value, const char *name) = 0;  	virtual BOOL		unpackU16(U16 &value, const char *name) = 0; +    BOOL                unpackU16s(U16 *value, S32 count, const char *name); +  +    virtual BOOL		packS16(const S16 value, const char *name) = 0; +    virtual BOOL		unpackS16(S16 &value, const char *name) = 0; +    BOOL                unpackS16s(S16 *value, S32 count, const char *name);  	virtual BOOL		packU32(const U32 value, const char *name) = 0;  	virtual BOOL		unpackU32(U32 &value, const char *name) = 0; @@ -69,6 +74,7 @@ public:  	virtual BOOL		packF32(const F32 value, const char *name) = 0;  	virtual BOOL		unpackF32(F32 &value, const char *name) = 0; +    BOOL                unpackF32s(F32 *values, S32 count, const char *name);  	// Packs a float into an integer, using the given size  	// and picks the right U* data type to pack into. @@ -82,6 +88,7 @@ public:  	virtual BOOL		packColor4U(const LLColor4U &value, const char *name) = 0;  	virtual BOOL		unpackColor4U(LLColor4U &value, const char *name) = 0; +    BOOL                unpackColor4Us(LLColor4U *values, S32 count, const char *name);  	virtual BOOL		packVector2(const LLVector2 &value, const char *name) = 0;  	virtual BOOL		unpackVector2(LLVector2 &value, const char *name) = 0; @@ -94,6 +101,7 @@ public:  	virtual BOOL		packUUID(const LLUUID &value, const char *name) = 0;  	virtual BOOL		unpackUUID(LLUUID &value, const char *name) = 0; +    BOOL                unpackUUIDs(LLUUID *values, S32 count, const char *name);  			U32			getPassFlags() const	{ return mPassFlags; }  			void		setPassFlags(U32 flags)	{ mPassFlags = flags; }  protected: @@ -139,6 +147,9 @@ public:  	/*virtual*/ BOOL		packU16(const U16 value, const char *name);  	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name); +    /*virtual*/ BOOL		packS16(const S16 value, const char *name); +    /*virtual*/ BOOL		unpackS16(S16 &value, const char *name); +  	/*virtual*/ BOOL		packU32(const U32 value, const char *name);  	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name); @@ -247,6 +258,9 @@ public:  	/*virtual*/ BOOL		packU16(const U16 value, const char *name);  	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name); +    /*virtual*/ BOOL		packS16(const S16 value, const char *name); +    /*virtual*/ BOOL		unpackS16(S16 &value, const char *name); +  	/*virtual*/ BOOL		packU32(const U32 value, const char *name);  	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name); @@ -375,6 +389,9 @@ public:  	/*virtual*/ BOOL		packU16(const U16 value, const char *name);  	/*virtual*/ BOOL		unpackU16(U16 &value, const char *name); +    /*virtual*/ BOOL		packS16(const S16 value, const char *name); +    /*virtual*/ BOOL		unpackS16(S16 &value, const char *name); +  	/*virtual*/ BOOL		packU32(const U32 value, const char *name);  	/*virtual*/ BOOL		unpackU32(U32 &value, const char *name); diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index fba5b7453d..219b1855d2 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -281,6 +281,13 @@ char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->  char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags");  char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended");  char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols"); +char const* const _PREHASH_ChatWhisperRange = LLMessageStringTable::getInstance()->getString("ChatWhisperRange"); +char const* const _PREHASH_ChatNormalRange = LLMessageStringTable::getInstance()->getString("ChatNormalRange"); +char const* const _PREHASH_ChatShoutRange = LLMessageStringTable::getInstance()->getString("ChatShoutRange"); +char const* const _PREHASH_ChatWhisperOffset = LLMessageStringTable::getInstance()->getString("ChatWhisperOffset"); +char const* const _PREHASH_ChatNormalOffset = LLMessageStringTable::getInstance()->getString("ChatNormalOffset"); +char const* const _PREHASH_ChatShoutOffset = LLMessageStringTable::getInstance()->getString("ChatShoutOffset"); +char const* const _PREHASH_ChatFlags = LLMessageStringTable::getInstance()->getString("ChatFlags");  char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult");  char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate");  char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock"); @@ -309,6 +316,7 @@ char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()-  char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2");  char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3");  char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4"); +char const* const _PREHASH_RegionInfo5 = LLMessageStringTable::getInstance()->getString("RegionInfo5");  char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor");  char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID");  char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 4f72c01ddf..8f6ee5a327 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -281,6 +281,13 @@ extern char const* const _PREHASH_PricePerMeter;  extern char const* const _PREHASH_RegionFlags;  extern char const* const _PREHASH_RegionFlagsExtended;  extern char const* const _PREHASH_RegionProtocols; +extern char const* const _PREHASH_ChatWhisperRange; +extern char const* const _PREHASH_ChatNormalRange; +extern char const* const _PREHASH_ChatShoutRange; +extern char const* const _PREHASH_ChatWhisperOffset; +extern char const* const _PREHASH_ChatNormalOffset; +extern char const* const _PREHASH_ChatShoutOffset; +extern char const* const _PREHASH_ChatFlags;  extern char const* const _PREHASH_VoteResult;  extern char const* const _PREHASH_ParcelDirFeeEstimate;  extern char const* const _PREHASH_ModifyBlock; @@ -309,6 +316,7 @@ extern char const* const _PREHASH_DuplicateFlags;  extern char const* const _PREHASH_RegionInfo2;  extern char const* const _PREHASH_RegionInfo3;  extern char const* const _PREHASH_RegionInfo4; +extern char const* const _PREHASH_RegionInfo5;  extern char const* const _PREHASH_TextColor;  extern char const* const _PREHASH_SlaveID;  extern char const* const _PREHASH_Charter; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 53b83a40d7..67c225d25d 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -114,6 +114,35 @@ const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; //  // can't be divided by 2.   See DEV-19108  const F32	TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000); +struct material_id_type // originally from llrendermaterialtable +{ +    material_id_type() +    { +        memset((void*)m_value, 0, sizeof(m_value)); +    } + +    bool operator==(const material_id_type& other) const +    { +        return (memcmp(m_value, other.m_value, sizeof(m_value)) == 0); +    } + +    bool operator!=(const material_id_type& other) const +    { +        return !operator==(other); +    } + +    bool isNull() const +    { +        return (memcmp(m_value, s_null_id, sizeof(m_value)) == 0); +    } + +    U8 m_value[MATERIAL_ID_SIZE]; // server side this is MD5RAW_BYTES + +    static const U8 s_null_id[MATERIAL_ID_SIZE]; +}; + +const U8 material_id_type::s_null_id[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +  //static   // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global  // TODO -- eliminate this global from the codebase! @@ -1079,50 +1108,85 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa  	return (S32)(cur_ptr - start_loc);  } -S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type) -{ -	U8 *start_loc = cur_ptr; -	U64 i; -	htolememcpy(data_ptr,cur_ptr, type,data_size); -	cur_ptr += data_size; - -	for (i = 1; i < face_count; i++) -	{ -		// Already unswizzled, don't need to unswizzle it again! -		memcpy(data_ptr+(i*data_size),data_ptr,data_size);	/* Flawfinder: ignore */  -	} -	 -	while ((cur_ptr < buffer_end) && (*cur_ptr != 0)) -	{ -		LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL; -		i = 0; -		while (*cur_ptr & 0x80) -		{ -			i |= ((*cur_ptr++) & 0x7F); -			i = i << 7; -		} - -		i |= *cur_ptr++; - -		for (S32 j = 0; j < face_count; j++) -		{ -			if (i & 0x01) -			{ -				htolememcpy(data_ptr+(j*data_size),cur_ptr,type,data_size); -				LL_DEBUGS("TEFieldDecode") << "Assigning " ; -				char foo[64]; -				sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1)); -				LL_CONT << foo << " to face " << j << LL_ENDL; -			} -			i = i >> 1; -		} -		cur_ptr += data_size;		 -	} -	llassert(cur_ptr <= buffer_end); // buffer underrun -	return (S32)(cur_ptr - start_loc); +namespace +{ +    template< typename T > +    bool unpack_TEField(T dest[], U8 dest_count, U8 * &source, U8 *source_end, EMsgVariableType type) +    { +        const size_t size(sizeof(T)); + +        LL_DEBUGS("TEXTUREENTRY") << "Request to read items of size " << size << " with swizzle " << type << " froum buffer sized " << (source_end - source) << LL_ENDL; + +        if ((source + size + 1) > source_end) +        { +            // we add 1 above to take into account the byte that we know must follow the value. +            LL_WARNS("TEXTUREENTRY") << "Buffer exhausted! Requires " << size << " + 1 bytes for default, " << (source_end - source) << " bytes remaning." << LL_ENDL; +            source = source_end; +            return false; +        } + +        // Extract the default value and fill the array.  +        htolememcpy(dest, source, type, size); +        source += size; +        for (S32 idx = 1; idx < dest_count; ++idx) +        { +            dest[idx] = dest[0]; +        } + +        while (source < source_end) +        { +            U64 index_flags(0); +            U8  sbit(0); + +            // Unpack the variable length bitfield. Each bit represents whether the following  +            // value will be placed at the corresponding array index. +            do +            { +                if (source >= source_end) +                { +                    LL_WARNS("TEXTUREENTRY") << "Buffer exhausted! Reading index flags." << LL_ENDL; +                    source = source_end; +                    return false; +                } + +                sbit = *source++; +                index_flags <<= 7;    // original code had this after? +                index_flags |= (sbit & 0x7F); +            } while (sbit & 0x80); + +            if (!index_flags) +            {   // We've hit the terminating 0 byte. +                break; +            } + +            if ((source + size + 1) > source_end) +            { +                // we add 1 above to take into account the byte that we know must follow the value. +                LL_WARNS("TEXTUREENTRY") << "Buffer exhausted! Requires " << size << " + 1 bytes for default, " << (source_end - source) << " bytes remaning." << LL_ENDL; +                source = source_end; +                return false; +            } + +            // get the value for the indexs. +            T value; +            htolememcpy(&value, source, type, size); +            source += size; + +            for (S32 idx = 0; idx < dest_count; idx++) +            { +                if (index_flags & 1ULL << idx) +                { +                    dest[idx] = value; +                } +            } + +        } +        return true; +    }  } +  // Pack information about all texture entries into container:  // { TextureEntry Variable 2 }  // Includes information about image ID, color, scale S,T, offset S,T and rotation @@ -1298,9 +1362,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)  {  	S32 retval = 0; -   // temp buffer for material ID processing -   // data will end up in tec.material_id[]	 -   U8 material_data[LLTEContents::MAX_TES*16]; +    // temp buffer for material ID processing +    // data will end up in tec.material_id[]	 +    material_id_type material_data[LLTEContents::MAX_TES];  	if (block_num < 0)  	{ @@ -1316,54 +1380,49 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name  		tec.face_count = 0;  		return retval;  	} +    else if (tec.size >= LLTEContents::MAX_TE_BUFFER) +    { +        LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL; +        tec.size = LLTEContents::MAX_TE_BUFFER - 1; +    } -	if (block_num < 0) -	{ -		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER); -	} -	else -	{ -		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); -	} +    // if block_num < 0 ask for block 0 +    mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, std::max(block_num, 0), LLTEContents::MAX_TE_BUFFER - 1); -	 +    // The last field is not zero terminated.   +    // Rather than special case the upack functions.  Just make it 0x00 terminated. +    tec.packed_buffer[tec.size] = 0x00; +    ++tec.size;  	tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);  	U8 *cur_ptr = tec.packed_buffer; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8); - -	if (cur_ptr < tec.packed_buffer + tec.size) -	{ -		cur_ptr++; -		cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID); -	} -	else -	{ -		memset(material_data, 0, sizeof(material_data)); +    LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffere sized: " << tec.size << LL_ENDL; +    U8 *buffer_end = tec.packed_buffer + tec.size; + +    if (!(  unpack_TEField<LLUUID>(tec.image_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID) && +            unpack_TEField<LLColor4U>(tec.colors, tec.face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<F32>(tec.scale_s, tec.face_count, cur_ptr, buffer_end, MVT_F32) && +            unpack_TEField<F32>(tec.scale_t, tec.face_count, cur_ptr, buffer_end, MVT_F32) && +            unpack_TEField<S16>(tec.offset_s, tec.face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<S16>(tec.offset_t, tec.face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<S16>(tec.image_rot, tec.face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<U8>(tec.bump, tec.face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<U8>(tec.media_flags, tec.face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<U8>(tec.glow, tec.face_count, cur_ptr, buffer_end, MVT_U8))) +    { +        LL_WARNS("TEXTUREENTRY") << "Failure parsing Texture Entry Message due to malformed TE Field! Dropping changes on the floor. " << LL_ENDL; +        return 0; +    } + +	if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, tec.face_count, cur_ptr, buffer_end, MVT_LLUUID)) +	{ +		memset((void*)material_data, 0, sizeof(material_data));  	}  	for (U32 i = 0; i < tec.face_count; i++)  	{ -		tec.material_ids[i].set(&material_data[i * 16]); +		tec.material_ids[i].set(&(material_data[i]));  	}  	retval = 1; @@ -1375,7 +1434,6 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)  	S32 retval = 0;  	LLColor4 color; -	LLColor4U coloru;  	for (U32 i = 0; i < tec.face_count; i++)  	{  		LLUUID& req_id = ((LLUUID*)tec.image_data)[i]; @@ -1388,20 +1446,15 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)  		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);  		retval |= setTEMaterialID(i, tec.material_ids[i]); -		coloru = LLColor4U(tec.colors + 4*i); -  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)  		// as all zeros.  However, the subtraction and addition must be done in unsigned  		// byte space, not in float space, otherwise off-by-one errors occur. JC -		color.mV[VRED]		= F32(255 - coloru.mV[VRED])   / 255.f; -		color.mV[VGREEN]	= F32(255 - coloru.mV[VGREEN]) / 255.f; -		color.mV[VBLUE]		= F32(255 - coloru.mV[VBLUE])  / 255.f; -		color.mV[VALPHA]	= F32(255 - coloru.mV[VALPHA]) / 255.f; +		color.mV[VRED]		= F32(255 - tec.colors[i].mV[VRED])   / 255.f; +		color.mV[VGREEN]	= F32(255 - tec.colors[i].mV[VGREEN]) / 255.f; +		color.mV[VBLUE]		= F32(255 - tec.colors[i].mV[VBLUE])  / 255.f; +		color.mV[VALPHA]	= F32(255 - tec.colors[i].mV[VALPHA]) / 255.f;  		retval |= setTEColor(i, color); - -		 -  	}  	return retval; @@ -1423,24 +1476,32 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  	const U32 MAX_TES = 45;  	// Avoid construction of 32 UUIDs per call -	static LLUUID image_ids[MAX_TES];  	static LLMaterialID material_ids[MAX_TES]; -	U8     image_data[MAX_TES*16]; -	U8	   colors[MAX_TES*4]; -	F32    scale_s[MAX_TES]; -	F32    scale_t[MAX_TES]; -	S16    offset_s[MAX_TES]; -	S16    offset_t[MAX_TES]; -	S16    image_rot[MAX_TES]; -	U8	   bump[MAX_TES]; -	U8	   media_flags[MAX_TES]; -    U8     glow[MAX_TES]; -	U8     material_data[MAX_TES*16]; - -	const U32 MAX_TE_BUFFER = 4096; -	U8 packed_buffer[MAX_TE_BUFFER]; -	U8 *cur_ptr = packed_buffer; +    const U32 MAX_TE_BUFFER = 4096; +    U8 packed_buffer[MAX_TE_BUFFER]; +    memset((void*)packed_buffer, 0, MAX_TE_BUFFER); + +    LLUUID      image_data[MAX_TES]; +    LLColor4U   colors[MAX_TES]; +    F32         scale_s[MAX_TES]; +    F32         scale_t[MAX_TES]; +    S16         offset_s[MAX_TES]; +    S16         offset_t[MAX_TES]; +    S16         image_rot[MAX_TES]; +    U8          bump[MAX_TES]; +    U8          media_flags[MAX_TES]; +    U8          glow[MAX_TES]; +    material_id_type material_data[MAX_TES]; +     +    memset((void*)scale_s, 0, sizeof(scale_s)); +    memset((void*)scale_t, 0, sizeof(scale_t)); +    memset((void*)offset_s, 0, sizeof(offset_s)); +    memset((void*)offset_t, 0, sizeof(offset_t)); +    memset((void*)image_rot, 0, sizeof(image_rot)); +    memset((void*)bump, 0, sizeof(bump)); +    memset((void*)media_flags, 0, sizeof(media_flags)); +    memset((void*)glow, 0, sizeof(glow));  	S32 size;  	U32 face_count = 0; @@ -1456,50 +1517,52 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  	{  		return retval;  	} +    else if (size >= MAX_TE_BUFFER) +    { +        LL_WARNS("TEXTUREENTRY") << "Excessive buffer size detected in Texture Entry! Truncating." << LL_ENDL; +        size = MAX_TE_BUFFER - 1; +    } +    // The last field is not zero terminated.   +    // Rather than special case the upack functions.  Just make it 0x00 terminated. +    packed_buffer[size] = 0x00; +    ++size;  	face_count = llmin((U32) getNumTEs(), MAX_TES);  	U32 i; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8); -	cur_ptr++; -	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8); -	if (cur_ptr < packed_buffer + size) -	{ -		cur_ptr++; -		cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID); -	} -	else +    U8 *cur_ptr = packed_buffer; +    LL_DEBUGS("TEXTUREENTRY") << "Texture Entry with buffer sized: " << size << LL_ENDL; +    U8 *buffer_end = packed_buffer + size; + +    if (!(  unpack_TEField<LLUUID>(image_data, face_count, cur_ptr, buffer_end, MVT_LLUUID) && +            unpack_TEField<LLColor4U>(colors, face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<F32>(scale_s, face_count, cur_ptr, buffer_end, MVT_F32) && +            unpack_TEField<F32>(scale_t, face_count, cur_ptr, buffer_end, MVT_F32) && +            unpack_TEField<S16>(offset_s, face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<S16>(offset_t, face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<S16>(image_rot, face_count, cur_ptr, buffer_end, MVT_S16) && +            unpack_TEField<U8>(bump, face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<U8>(media_flags, face_count, cur_ptr, buffer_end, MVT_U8) && +            unpack_TEField<U8>(glow, face_count, cur_ptr, buffer_end, MVT_U8))) +    { +        LL_WARNS("TEXTUREENTRY") << "Failure parsing Texture Entry Message due to malformed TE Field! Dropping changes on the floor. " << LL_ENDL; +        return 0; +    } + +	if (cur_ptr >= buffer_end || !unpack_TEField<material_id_type>(material_data, face_count, cur_ptr, buffer_end, MVT_LLUUID))  	{ -		memset(material_data, 0, sizeof(material_data)); +		memset((void*)material_data, 0, sizeof(material_data));  	}  	for (i = 0; i < face_count; i++)  	{ -		memcpy(image_ids[i].mData,&image_data[i*16],16);	/* Flawfinder: ignore */ 	 -		material_ids[i].set(&material_data[i * 16]); +		material_ids[i].set(&(material_data[i]));  	}  	LLColor4 color; -	LLColor4U coloru;  	for (i = 0; i < face_count; i++)  	{ -		retval |= setTETexture(i, image_ids[i]); +        retval |= setTETexture(i, ((LLUUID*)image_data)[i]);  		retval |= setTEScale(i, scale_s[i], scale_t[i]);  		retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);  		retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI); @@ -1507,15 +1570,14 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  		retval |= setTEMediaTexGen(i, media_flags[i]);  		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);  		retval |= setTEMaterialID(i, material_ids[i]); -		coloru = LLColor4U(colors + 4*i);  		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)  		// as all zeros.  However, the subtraction and addition must be done in unsigned  		// byte space, not in float space, otherwise off-by-one errors occur. JC -		color.mV[VRED]		= F32(255 - coloru.mV[VRED])   / 255.f; -		color.mV[VGREEN]	= F32(255 - coloru.mV[VGREEN]) / 255.f; -		color.mV[VBLUE]		= F32(255 - coloru.mV[VBLUE])  / 255.f; -		color.mV[VALPHA]	= F32(255 - coloru.mV[VALPHA]) / 255.f; +		color.mV[VRED]		= F32(255 - colors[i].mV[VRED])   / 255.f; + 		color.mV[VGREEN]	= F32(255 - colors[i].mV[VGREEN]) / 255.f; + 		color.mV[VBLUE]		= F32(255 - colors[i].mV[VBLUE])  / 255.f; + 		color.mV[VALPHA]	= F32(255 - colors[i].mV[VALPHA]) / 255.f;  		retval |= setTEColor(i, color);  	} diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index b1f8112223..309b18faa9 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -330,8 +330,8 @@ struct LLTEContents  {  	static const U32 MAX_TES = 45; -	U8     image_data[MAX_TES*16]; -	U8	  colors[MAX_TES*4]; +    LLUUID      image_data[MAX_TES]; +    LLColor4U   colors[MAX_TES];  	F32    scale_s[MAX_TES];  	F32    scale_t[MAX_TES];  	S16    offset_s[MAX_TES]; @@ -423,7 +423,6 @@ public:  	void copyTEs(const LLPrimitive *primitive);  	S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; -	S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);  	BOOL packTEMessage(LLMessageSystem *mesgsys) const;  	BOOL packTEMessage(LLDataPacker &dp) const;  	S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ff72417867..d92f10bdbb 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -184,6 +184,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)  	mFontShadow(p.font_shadow),  	mPopupMenuHandle(),  	mReadOnly(p.read_only), +	mSkipTripleClick(false),  	mSkipLinkUnderline(p.skip_link_underline),  	mSpellCheck(p.spellcheck),  	mSpellCheckStart(-1), @@ -1017,6 +1018,11 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)  	// handle triple click  	if (!mTripleClickTimer.hasExpired())  	{ +		if (mSkipTripleClick) +		{ +			return TRUE; +		} +		  		S32 real_line = getLineNumFromDocIndex(mCursorPos, false);  		S32 line_start = -1;  		S32 line_end = -1; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 4e966b7cef..2e2e1b9833 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -699,7 +699,7 @@ protected:  	bool						mPlainText;			// didn't use Image or Icon segments  	bool						mAutoIndent;  	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes - +	bool						mSkipTripleClick;  	bool						mSkipLinkUnderline;  	// support widgets diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 0afd32f332..4dc2a6a597 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -45,7 +45,9 @@ LLTextBox::LLTextBox(const LLTextBox::Params& p)  :	LLTextBase(p),  	mClickedCallback(NULL),  	mShowCursorHand(true) -{} +{ +	mSkipTripleClick = true; +}  LLTextBox::~LLTextBox()  {} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c0166f158e..53eed5697a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12663,6 +12663,17 @@        <key>Value</key>        <integer>50</integer>      </map> +    <key>TextureSaveLocation</key> +    <map> +      <key>Comment</key> +      <string>Current location for bulk saving textures to disk</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string /> +    </map>      <key>ThrottleBandwidthKBPS</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl index b768d609f4..d87403c78f 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl @@ -43,13 +43,13 @@ void default_lighting()  {  	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy); -	color *= vertex_color; -  	if (color.a < minimum_alpha)  	{  		discard;  	} -	 + +	color *= vertex_color; +  	color.rgb = atmosLighting(color.rgb);  	color.rgb = scaleSoftClip(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl index d04cd79f4b..37cac5f437 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl @@ -43,13 +43,13 @@ void fullbright_lighting_water()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy); -	color.rgb *= vertex_color.rgb; -  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = fullbrightAtmosTransport(color.rgb);  	frag_color = applyWaterFog(color); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl index 3b9c04b22b..c98db4795c 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl @@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;  void fullbright_lighting_water()  { -	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color; +	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = fullbrightAtmosTransport(color.rgb);  	frag_color = applyWaterFog(color); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl index 0916797259..9c89c09573 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl @@ -41,13 +41,13 @@ void default_lighting_water()  {  	vec4 color = diffuseLookup(vary_texcoord0.xy); -	color.rgb *= vertex_color.rgb; -  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = atmosLighting(color.rgb);  	frag_color = applyWaterFog(color); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl index f2a84f1d42..9de7a03180 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl @@ -43,13 +43,13 @@ void default_lighting_water()  {  	vec4 color = texture2D(diffuseMap,vary_texcoord0.xy); -	color.rgb *= vertex_color.rgb; -  	if (color.a < minimum_alpha)  	{  		discard;  	} +	color.rgb *= vertex_color.rgb; +  	color.rgb = atmosLighting(color.rgb);  	color = applyWaterFog(color); diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi Binary files differindex 05977847b9..865e8bdeee 100644 --- a/indra/newview/installers/windows/lang_pl.nsi +++ b/indra/newview/installers/windows/lang_pl.nsi diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 7f18ea6fe2..be168ff5dd 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1049,13 +1049,14 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  	}  	// updating inventory +    LLWearableType* wearable_type_inst = LLWearableType::getInstance();  	// TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later  	// note: shirt is the first non-body part wearable item. Update if wearable order changes.  	// This loop should remove all clothing, but not any body parts  	for (S32 j = 0; j < (S32)LLWearableType::WT_COUNT; j++)  	{ -		if (LLWearableType::getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING) +		if (wearable_type_inst->getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING)  		{  			removeWearable((LLWearableType::EType)j, true, 0);  		} @@ -1075,7 +1076,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it  			new_wearable->setName(new_item->getName());  			new_wearable->setItemID(new_item->getUUID()); -			if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART) +			if (wearable_type_inst->getAssetType(type) == LLAssetType::AT_BODYPART)  			{  				// exactly one wearable per body part  				setWearable(type,0,new_wearable); @@ -1162,7 +1163,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearab  			if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&  				(old_item_id == new_item->getUUID()))  			{ -				LL_DEBUGS() << "No change to wearable asset and item: " << LLWearableType::getTypeName(type) << LL_ENDL; +				LL_DEBUGS() << "No change to wearable asset and item: " << LLWearableType::getInstance()->getTypeName(type) << LL_ENDL;  				return;  			} @@ -1594,7 +1595,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)  		return;  	} -	const BOOL disable_camera_switch = LLWearableType::getDisableCameraSwitch(wearable->getType()); +	const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType());  	LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance");  	LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch);  } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e8a3305645..268999bd2a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -957,7 +957,7 @@ void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, L  		// runway skip here?  	} -	LL_INFOS() << "HP " << holder->index() << " recovered item link for type " << type << LL_ENDL; +	LL_INFOS("Avatar") << "HP " << holder->index() << " recovered item link for type " << type << LL_ENDL;  	holder->eraseTypeToLink(type);  	// Add wearable to FoundData for actual wearing  	LLViewerInventoryItem *item = gInventory.getItem(item_id); @@ -1021,8 +1021,8 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type  		// Try to recover by replacing missing wearable with a new one.  	LLNotificationsUtil::add("ReplacedMissingWearable"); -	LL_DEBUGS() << "Wearable " << LLWearableType::getTypeLabel(type) -				<< " could not be downloaded.  Replaced inventory item with default wearable." << LL_ENDL; +	LL_DEBUGS("Avatar") << "Wearable of type '" << LLWearableType::getInstance()->getTypeName(type) +				<< "' could not be downloaded.  Replaced inventory item with default wearable." << LL_ENDL;  	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);  	// Add a new one in the lost and found folder. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f518704e06..2040151008 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -779,10 +779,6 @@ bool LLAppViewer::init()  	// Start of the application  	// -	// initialize LLWearableType translation bridge. -	// Memory will be cleaned up in ::cleanupClass() -	LLWearableType::initParamSingleton(new LLUITranslationBridge()); -      // initialize the LLSettingsType translation bridge.      LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();      LLSettingsType::initParamSingleton(trans); @@ -804,6 +800,7 @@ bool LLAppViewer::init()  	//  	init_default_trans_args(); +    // inits from settings.xml and from strings.xml  	if (!initConfiguration())  		return false; @@ -870,6 +867,10 @@ bool LLAppViewer::init()  	// Setup LLTrans after LLUI::initClass has been called.  	initStrings(); +    // initialize LLWearableType translation bridge. +    // Will immediately use LLTranslationBridge to init LLWearableDictionary +    LLWearableType::initParamSingleton(trans); +  	// Setup notifications after LLUI::initClass() has been called.  	LLNotifications::instance();  	LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index b31981b235..aa2ba752b7 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -74,7 +74,7 @@ protected:  		}  		// Set proper label for the "Create new <WEARABLE_TYPE>" menu item. -		std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type)); +		std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstance()->getTypeName(w_type));  		menu_item->setLabel(new_label);  	} diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 347997a69a..c76920c9ce 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -677,8 +677,12 @@ void LLFavoritesBarCtrl::changed(U32 mask)  //virtual  void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)  { +    S32 delta_width = width - getRect().getWidth(); +    S32 delta_height = height - getRect().getHeight(); + +    bool force_update = delta_width || delta_height || sForceReshape;  	LLUICtrl::reshape(width, height, called_from_parent); -	updateButtons(); +	updateButtons(force_update);  }  void LLFavoritesBarCtrl::draw() @@ -741,8 +745,13 @@ const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()  	return button_params;  } -void LLFavoritesBarCtrl::updateButtons() +void LLFavoritesBarCtrl::updateButtons(bool force_update)  { +    if (LLApp::isExiting()) +    { +        return; +    } +  	mItems.clear();  	if (!collectFavoriteItems(mItems)) @@ -773,28 +782,29 @@ void LLFavoritesBarCtrl::updateButtons()  	const child_list_t* childs = getChildList();  	child_list_const_iter_t child_it = childs->begin();  	int first_changed_item_index = 0; -	int rightest_point = getRect().mRight - mMoreTextBox->getRect().getWidth(); -	//lets find first changed button -	while (child_it != childs->end() && first_changed_item_index < mItems.size()) -	{ -		LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (*child_it); -		if (button) -		{ -			const LLViewerInventoryItem *item = mItems[first_changed_item_index].get(); -			if (item) -			{ -			    // an child's order  and mItems  should be same -				if (button->getLandmarkId() != item->getUUID() // sort order has been changed -					|| button->getLabelSelected() != item->getName() // favorite's name has been changed -					|| button->getRect().mRight < rightest_point) // favbar's width has been changed -				{ -					break; -				} -			} -			first_changed_item_index++; -		} -		child_it++; -	} +    if (!force_update) +    { +        //lets find first changed button +        while (child_it != childs->end() && first_changed_item_index < mItems.size()) +        { +            LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (*child_it); +            if (button) +            { +                const LLViewerInventoryItem *item = mItems[first_changed_item_index].get(); +                if (item) +                { +                    // an child's order  and mItems  should be same +                    if (button->getLandmarkId() != item->getUUID() // sort order has been changed +                        || button->getLabelSelected() != item->getName()) // favorite's name has been changed +                    { +                        break; +                    } +                } +                first_changed_item_index++; +            } +            child_it++; +        } +    }  	// now first_changed_item_index should contains a number of button that need to change  	if (first_changed_item_index <= mItems.size()) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 571208aa31..d4a6f7b06b 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -75,7 +75,7 @@ public:  	void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; }  protected: -	void updateButtons(); +    void updateButtons(bool force_update = false);  	LLButton* createButton(const LLPointer<LLViewerInventoryItem> item, const LLButton::Params& button_params, S32 x_offset );  	const LLButton::Params& getButtonParams();  	BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items); diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index adc7f71586..4b22f7427b 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -248,6 +248,29 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)  		region_flags = flags;  	} +	if (msg->has(_PREHASH_RegionInfo5)) +	{ +		F32 chat_whisper_range; +		F32 chat_normal_range; +		F32 chat_shout_range; +		F32 chat_whisper_offset; +		F32 chat_normal_offset; +		F32 chat_shout_offset; +		U32 chat_flags; + +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset); +		msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags); + +		LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range +			<< " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset +			<< " chat flags: " << chat_flags << LL_ENDL; +	} +  	if (host != gAgent.getRegionHost())  	{  		// Update is for a different region than the one we're in. diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp index 595d584799..8ee7a72055 100644 --- a/indra/newview/llfloaterlinkreplace.cpp +++ b/indra/newview/llfloaterlinkreplace.cpp @@ -162,7 +162,7 @@ void LLFloaterLinkReplace::onStartClicked()  		else  		{  			LLSD args; -			args["TYPE"] = LLWearableType::getTypeName(source_item->getWearableType()); +			args["TYPE"] = LLWearableType::getInstance()->getTypeName(source_item->getWearableType());  			params.substitutions(args);  			LLNotifications::instance().add(params);  		} diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index bafebf7bc1..5f180908ca 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -2492,7 +2492,7 @@ BOOL LLPanelPreference::postBuild()  	}  	//////////////////////PanelSetup /////////////////// -	if (hasChild("max_bandwidth"), TRUE) +	if (hasChild("max_bandwidth", TRUE))  	{  		mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);  		gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2)); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ec1909d02a..17e55b5f2c 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -470,6 +470,29 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  		region_flags = flags;  	} +	if (msg->has(_PREHASH_RegionInfo5)) +	{ +		F32 chat_whisper_range; +		F32 chat_normal_range; +		F32 chat_shout_range; +		F32 chat_whisper_offset; +		F32 chat_normal_offset; +		F32 chat_shout_offset; +		U32 chat_flags; + +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset); +		msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags); + +		LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range +			<< " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset +			<< " chat flags: " << chat_flags << LL_ENDL; +	} +  	// GENERAL PANEL  	panel = tab->getChild<LLPanel>("General");  	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name)); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d35d8456be..4567388166 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5469,11 +5469,20 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		getClipboardEntries(true, items, disabled_items, flags);  		items.push_back(std::string("Texture Separator")); -		items.push_back(std::string("Save As")); -		if (!canSaveTexture()) -		{ -			disabled_items.push_back(std::string("Save As")); -		} +		 +        if ((flags & ITEM_IN_MULTI_SELECTION) != 0) +        { +            items.push_back(std::string("Save Selected As")); +        } +        else +        { +            items.push_back(std::string("Save As")); +            if (!canSaveTexture()) +            { +                disabled_items.push_back(std::string("Save As")); +            } +        } +  	}  	addLinkReplaceMenuOption(items, disabled_items);  	hide_context_entries(menu, items, disabled_items);	 @@ -5491,6 +5500,23 @@ void LLTextureBridge::performAction(LLInventoryModel* model, std::string action)  			preview_texture->saveAs();  		}  	} +    else if ("save_selected_as" == action) +    { +        openItem(); +        if (canSaveTexture()) +        { +            LLPreviewTexture* preview_texture = LLFloaterReg::getTypedInstance<LLPreviewTexture>("preview_texture", mUUID); +            if (preview_texture) +            { +                preview_texture->saveMultipleToFile(); +            } +        } +        else +        { +            LL_WARNS() << "You don't have permission to save " << getName() << " to disk." << LL_ENDL; +        } + +    }  	else LLItemBridge::performAction(model, action);  } @@ -6820,7 +6846,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  						disabled_items.push_back(std::string("Wearable Edit"));  					} -					if (LLWearableType::getAllowMultiwear(mWearableType)) +					if (LLWearableType::getInstance()->getAllowMultiwear(mWearableType))  					{  						items.push_back(std::string("Wearable Add"));  						if (!gAgentWearables.canAddWearable(mWearableType)) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7a0ea8b668..267c4e07a3 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -47,6 +47,7 @@  #include "llappviewer.h"  #include "llavataractions.h"  #include "llclipboard.h" +#include "lldirpicker.h"  #include "lldonotdisturbnotificationstorage.h"  #include "llfloatersidepanelcontainer.h"  #include "llfocusmgr.h" @@ -2492,6 +2493,10 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root      {          LLAppearanceMgr::instance().removeItemsFromAvatar(ids);      } +    else if ("save_selected_as" == action) +    { +        (new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile(); +    }      else      {          std::set<LLFolderViewItem*>::iterator set_iter; @@ -2519,6 +2524,32 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root  	}  } +void LLInventoryAction::saveMultipleTextures(const std::vector<std::string>& filenames, std::set<LLFolderViewItem*> selected_items, LLInventoryModel* model) +{ +    gSavedSettings.setString("TextureSaveLocation", filenames[0]); +  +    LLMultiPreview* multi_previewp = new LLMultiPreview(); +    gFloaterView->addChild(multi_previewp); + +    LLFloater::setFloaterHost(multi_previewp); + +    std::set<LLFolderViewItem*>::iterator set_iter; +    for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) +    { +        LLFolderViewItem* folder_item = *set_iter; +        if(!folder_item) continue; +        LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem(); +        if(!bridge) continue; +        bridge->performAction(model, "save_selected_as"); +    } + +    LLFloater::setFloaterHost(NULL); +    if (multi_previewp) +    { +        multi_previewp->openFloater(LLSD()); +    } +} +  void LLInventoryAction::removeItemFromDND(LLFolderView* root)  {      if(gAgent.isDoNotDisturb()) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 04eb962372..c1c4b8fe6c 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -466,6 +466,8 @@ struct LLInventoryAction  	static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root);  	static void removeItemFromDND(LLFolderView* root); +    static void saveMultipleTextures(const std::vector<std::string>& filenames, std::set<LLFolderViewItem*> selected_items, LLInventoryModel* model); +  	static const int sConfirmOnDeleteItemsNumber;  private: diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 81c001b8bd..44e493fdf4 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -196,7 +196,7 @@ const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx)  LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)  {  	const LLWearableType::EType wearable_type = LLWearableType::inventoryFlagsToWearableType(misc_flag); -	return LLWearableType::getIconName(wearable_type); +	return LLWearableType::getInstance()->getIconName(wearable_type);  }  LLInventoryType::EIconName LLInventoryIcon::assignSettingsIcon(U32 misc_flag) diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index 57a6ecb604..c7a0665630 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -33,237 +33,445 @@  using namespace std;  #include <comdef.h>  #include <Wbemidl.h> +#elif LL_DARWIN +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOKitLib.h>  #endif  unsigned char static_unique_id[] =  {0,0,0,0,0,0}; +unsigned char static_legacy_id[] =  {0,0,0,0,0,0};  bool static has_static_unique_id = false; +bool static has_static_legacy_id = false;  #if	LL_WINDOWS -class LLComInitialize +class LLWMIMethods  { -    HRESULT mHR;  public: -    LLComInitialize() +    LLWMIMethods() +    :   pLoc(NULL), +        pSvc(NULL)      { -        mHR = CoInitializeEx(0, COINIT_MULTITHREADED); -        if (FAILED(mHR)) -            LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hex << mHR << LL_ENDL; +        initCOMObjects();      } -    ~LLComInitialize() +    ~LLWMIMethods()      { -        if (SUCCEEDED(mHR)) -            CoUninitialize(); +        if (isInitialized()) +        { +            cleanCOMObjects(); +        }      } -}; -#endif //LL_WINDOWS +    bool isInitialized() { return SUCCEEDED(mHR); } +    bool getWindowsProductNumber(unsigned char *unique_id, size_t len); +    bool getDiskDriveSerialNumber(unsigned char *unique_id, size_t len); +    bool getProcessorSerialNumber(unsigned char *unique_id, size_t len); +    bool getMotherboardSerialNumber(unsigned char *unique_id, size_t len); +    bool getComputerSystemProductUUID(unsigned char *unique_id, size_t len); +    bool getGenericSerialNumber(const BSTR &select, const LPCWSTR &variable, unsigned char *unique_id, size_t len, bool validate_as_uuid = false); -// get an unique machine id. -// NOT THREAD SAFE - do before setting up threads. -// MAC Address doesn't work for Windows 7 since the first returned hardware MAC address changes with each reboot,  Go figure?? +private: +    void initCOMObjects(); +    void cleanCOMObjects(); -S32 LLMachineID::init() +    HRESULT mHR; +    IWbemLocator *pLoc; +    IWbemServices *pSvc; +}; + + +void LLWMIMethods::initCOMObjects()  { -    size_t len = sizeof(static_unique_id); -    memset(static_unique_id, 0, len); -    S32 ret_code = 0; -#if	LL_WINDOWS  # pragma comment(lib, "wbemuuid.lib") +    // Step 1: -------------------------------------------------- +    // Initialize COM. ------------------------------------------ -        // algorithm to detect BIOS serial number found at: -        // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx -        // we can't use the MAC address since on Windows 7, the first returned MAC address changes with every reboot. +    mHR = CoInitializeEx(0, COINIT_MULTITHREADED); +    if (FAILED(mHR)) +    { +        LL_DEBUGS("AppInit") << "Failed to initialize COM library. Error code = 0x" << hex << mHR << LL_ENDL; +        return; +    } +    // Step 2: -------------------------------------------------- +    // Set general COM security levels -------------------------- +    // Note: If you are using Windows 2000, you need to specify - +    // the default authentication credentials for a user by using +    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ---- +    // parameter of CoInitializeSecurity ------------------------ + +    mHR = CoInitializeSecurity( +        NULL, +        -1,                          // COM authentication +        NULL,                        // Authentication services +        NULL,                        // Reserved +        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication  +        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation   +        NULL,                        // Authentication info +        EOAC_NONE,                   // Additional capabilities  +        NULL                         // Reserved +    ); + +    if (FAILED(mHR)) +    { +        LL_WARNS("AppInit") << "Failed to initialize security. Error code = 0x" << hex << mHR << LL_ENDL; +        CoUninitialize(); +        return;               // Program has failed. +    } -        HRESULT hres; +    // Step 3: --------------------------------------------------- +    // Obtain the initial locator to WMI ------------------------- -        // Step 1: -------------------------------------------------- -        // Initialize COM. ------------------------------------------ +    mHR = CoCreateInstance( +        CLSID_WbemLocator, +        0, +        CLSCTX_INPROC_SERVER, +        IID_IWbemLocator, (LPVOID *)&pLoc); -        LLComInitialize comInit; +    if (FAILED(mHR)) +    { +        LL_WARNS("AppInit") << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << mHR << LL_ENDL; +        CoUninitialize(); +        return;               // Program has failed. +    } -        // Step 2: -------------------------------------------------- -        // Set general COM security levels -------------------------- -        // Note: If you are using Windows 2000, you need to specify - -        // the default authentication credentials for a user by using -        // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ---- -        // parameter of CoInitializeSecurity ------------------------ +    // Step 4: ----------------------------------------------------- +    // Connect to WMI through the IWbemLocator::ConnectServer method + +    // Connect to the root\cimv2 namespace with +    // the current user and obtain pointer pSvc +    // to make IWbemServices calls. +    mHR = pLoc->ConnectServer( +        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace +        NULL,                    // User name. NULL = current user +        NULL,                    // User password. NULL = current +        0,                       // Locale. NULL indicates current +        NULL,                    // Security flags. +        0,                       // Authority (e.g. Kerberos) +        0,                       // Context object  +        &pSvc                    // pointer to IWbemServices proxy +    ); + +    if (FAILED(mHR)) +    { +        LL_WARNS("AppInit") << "Could not connect. Error code = 0x" << hex << mHR << LL_ENDL; +        pLoc->Release(); +        CoUninitialize(); +        return;               // Program has failed. +    } -        hres =  CoInitializeSecurity( -            NULL,  -            -1,                          // COM authentication -            NULL,                        // Authentication services -            NULL,                        // Reserved -            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication  -            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation   -            NULL,                        // Authentication info -            EOAC_NONE,                   // Additional capabilities  -            NULL                         // Reserved -            ); +    LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL; -                           -        if (FAILED(hres)) -        { -            LL_WARNS("AppInit") << "Failed to initialize security. Error code = 0x"  << hex << hres << LL_ENDL; -            return 1;                    // Program has failed. -        } -         -        // Step 3: --------------------------------------------------- -        // Obtain the initial locator to WMI ------------------------- - -        IWbemLocator *pLoc = NULL; - -        hres = CoCreateInstance( -            CLSID_WbemLocator,              -            0,  -            CLSCTX_INPROC_SERVER,  -            IID_IWbemLocator, (LPVOID *) &pLoc); -      -        if (FAILED(hres)) -        { -            LL_WARNS("AppInit") << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << LL_ENDL; -            return 1;                 // Program has failed. -        } +    // Step 5: -------------------------------------------------- +    // Set security levels on the proxy ------------------------- -        // Step 4: ----------------------------------------------------- -        // Connect to WMI through the IWbemLocator::ConnectServer method - -        IWbemServices *pSvc = NULL; -    	 -        // Connect to the root\cimv2 namespace with -        // the current user and obtain pointer pSvc -        // to make IWbemServices calls. -        hres = pLoc->ConnectServer( -             _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace -             NULL,                    // User name. NULL = current user -             NULL,                    // User password. NULL = current -             0,                       // Locale. NULL indicates current -             NULL,                    // Security flags. -             0,                       // Authority (e.g. Kerberos) -             0,                       // Context object  -             &pSvc                    // pointer to IWbemServices proxy -             ); -         -        if (FAILED(hres)) -        { -            LL_WARNS("AppInit") << "Could not connect. Error code = 0x"  << hex << hres << LL_ENDL; -            pLoc->Release();      -            return 1;                // Program has failed. -        } +    mHR = CoSetProxyBlanket( +        pSvc,                        // Indicates the proxy to set +        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx +        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx +        NULL,                        // Server principal name  +        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx  +        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx +        NULL,                        // client identity +        EOAC_NONE                    // proxy capabilities  +    ); + +    if (FAILED(mHR)) +    { +        LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x" << hex << mHR << LL_ENDL; +        cleanCOMObjects(); +        return;               // Program has failed. +    } +} + + +void LLWMIMethods::cleanCOMObjects() +{ +    pSvc->Release(); +    pLoc->Release(); +    CoUninitialize(); +} + +bool LLWMIMethods::getWindowsProductNumber(unsigned char *unique_id, size_t len) +{ +    // wmic path Win32_ComputerSystemProduct get UUID +    return getGenericSerialNumber(bstr_t("SELECT * FROM Win32_OperatingSystem"), L"SerialNumber", unique_id, len); +} + +bool LLWMIMethods::getDiskDriveSerialNumber(unsigned char *unique_id, size_t len) +{ +    // wmic path Win32_DiskDrive get DeviceID,SerialNumber +    return getGenericSerialNumber(bstr_t("SELECT * FROM Win32_DiskDrive"), L"SerialNumber", unique_id, len); +} + +bool LLWMIMethods::getProcessorSerialNumber(unsigned char *unique_id, size_t len) +{ +    // wmic path Win32_Processor get DeviceID,ProcessorId +    return getGenericSerialNumber(bstr_t("SELECT * FROM Win32_Processor"), L"ProcessorId", unique_id, len); +} -        LL_DEBUGS("AppInit") << "Connected to ROOT\\CIMV2 WMI namespace" << LL_ENDL; +bool LLWMIMethods::getMotherboardSerialNumber(unsigned char *unique_id, size_t len) +{ +    // wmic path Win32_Processor get DeviceID,ProcessorId +    return getGenericSerialNumber(bstr_t("SELECT * FROM Win32_BaseBoard"), L"SerialNumber", unique_id, len); +} + +bool LLWMIMethods::getComputerSystemProductUUID(unsigned char *unique_id, size_t len) +{ +    // UUID from Win32_ComputerSystemProduct is motherboard's uuid and is identical to csproduct's uuid +    // wmic csproduct get name,identifyingnumber,uuid +    // wmic path Win32_ComputerSystemProduct get UUID +    return getGenericSerialNumber(bstr_t("SELECT * FROM Win32_ComputerSystemProduct"), L"UUID", unique_id, len, true); +} +bool LLWMIMethods::getGenericSerialNumber(const BSTR &select, const LPCWSTR &variable, unsigned char *unique_id, size_t len, bool validate_as_uuid) +{ +    if (!isInitialized()) +    { +        return false; +    } -        // Step 5: -------------------------------------------------- -        // Set security levels on the proxy ------------------------- +    HRESULT hres; -        hres = CoSetProxyBlanket( -           pSvc,                        // Indicates the proxy to set -           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx -           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx -           NULL,                        // Server principal name  -           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx  -           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx -           NULL,                        // client identity -           EOAC_NONE                    // proxy capabilities  -        ); +    // Step 6: -------------------------------------------------- +    // Use the IWbemServices pointer to make requests of WMI ---- -        if (FAILED(hres)) +    // For example, get the name of the operating system +    IEnumWbemClassObject* pEnumerator = NULL; +    hres = pSvc->ExecQuery( +        bstr_t("WQL"), +        select, +        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, +        NULL, +        &pEnumerator); + +    if (FAILED(hres)) +    { +        LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x" << hex << hres << LL_ENDL; +        return false;               // Program has failed. +    } + +    // Step 7: ------------------------------------------------- +    // Get the data from the query in step 6 ------------------- + +    IWbemClassObject *pclsObj = NULL; +    ULONG uReturn = 0; +    bool found = false; + +    while (pEnumerator) +    { +        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, +            &pclsObj, &uReturn); + +        if (0 == uReturn)          { -            LL_WARNS("AppInit") << "Could not set proxy blanket. Error code = 0x"   << hex << hres << LL_ENDL; -            pSvc->Release(); -            pLoc->Release();      -            return 1;               // Program has failed. +            break;          } -        // Step 6: -------------------------------------------------- -        // Use the IWbemServices pointer to make requests of WMI ---- - -        // For example, get the name of the operating system -        IEnumWbemClassObject* pEnumerator = NULL; -        hres = pSvc->ExecQuery( -            bstr_t("WQL"),  -            bstr_t("SELECT * FROM Win32_OperatingSystem"), -            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,  -            NULL, -            &pEnumerator); -         -        if (FAILED(hres)) +        VARIANT vtProp; + +        // Get the value of the Name property +        hr = pclsObj->Get(variable, 0, &vtProp, 0, 0); +        if (FAILED(hr))          { -            LL_WARNS("AppInit") << "Query for operating system name failed." << " Error code = 0x"  << hex << hres << LL_ENDL; -            pSvc->Release(); -            pLoc->Release(); -            return 1;               // Program has failed. +            LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL; +            pclsObj->Release(); +            pclsObj = NULL; +            continue;          } -        // Step 7: ------------------------------------------------- -        // Get the data from the query in step 6 ------------------- -      -        IWbemClassObject *pclsObj = NULL; -        ULONG uReturn = 0; -        -        while (pEnumerator) +        // use characters in the returned Serial Number to create a byte array of size len +        BSTR serialNumber(vtProp.bstrVal); +        unsigned int serial_size = SysStringLen(serialNumber); +        if (serial_size < 1) // < len?          { -            HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,  -                &pclsObj, &uReturn); +            VariantClear(&vtProp); +            pclsObj->Release(); +            pclsObj = NULL; +            continue; +        } -            if(0 == uReturn) +        if (validate_as_uuid) +        { +            std::wstring ws(serialNumber, serial_size); +            std::string str(ws.begin(), ws.end()); + +            if (!LLUUID::validate(str))              { -                break; +                VariantClear(&vtProp); +                pclsObj->Release(); +                pclsObj = NULL; +                continue;              } -            VARIANT vtProp; +            static const LLUUID f_uuid("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"); +            LLUUID id(str); -            // Get the value of the Name property -            hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); -            if (FAILED(hr)) +            if (id.isNull() || id == f_uuid)              { -                LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL; +                // Not unique id +                VariantClear(&vtProp);                  pclsObj->Release();                  pclsObj = NULL;                  continue;              } -            LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL; +        } +        LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL; -            // use characters in the returned Serial Number to create a byte array of size len -            BSTR serialNumber ( vtProp.bstrVal); -            unsigned int serial_size = SysStringLen(serialNumber); -            unsigned int j = 0; +        unsigned int j = 0; -            while (j < serial_size && vtProp.bstrVal[j] != 0) +        while (j < serial_size && vtProp.bstrVal[j] != 0) +        { +            for (unsigned int i = 0; i < len; i++)              { -                for (unsigned int i = 0; i < len; i++) +                if (j >= serial_size || vtProp.bstrVal[j] == 0) +                    break; + +                unique_id[i] = (unsigned int)(unique_id[i] + serialNumber[j]); +                j++; +            } +        } +        VariantClear(&vtProp); + +        pclsObj->Release(); +        pclsObj = NULL; +        found = true; +        break; +    } + +    // Cleanup +    // ======== + +    if (pEnumerator) +        pEnumerator->Release(); + +    return found; +} +#elif LL_DARWIN +bool getSerialNumber(unsigned char *unique_id, size_t len) +{ +    CFStringRef serial_cf_str = NULL; +    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, +                                                                 IOServiceMatching("IOPlatformExpertDevice")); +    if (platformExpert) +    { +        serial_cf_str = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert, +                                                                     CFSTR(kIOPlatformSerialNumberKey), +                                                                     kCFAllocatorDefault, 0); +        IOObjectRelease(platformExpert); +    } +     +    if (serial_cf_str) +    { +        char buffer[64] = {0}; +        std::string serial_str(""); +        if (CFStringGetCString(serial_cf_str, buffer, 64, kCFStringEncodingUTF8)) +        { +            serial_str = buffer; +        } + +        S32 serial_size = serial_str.size(); +         +        if(serial_str.size() > 0) +        { +            S32 j = 0; +            while (j < serial_size) +            { +                for (S32 i = 0; i < len; i++)                  { -                    if (j >= serial_size || vtProp.bstrVal[j] == 0) +                    if (j >= serial_size)                          break; -                     -                    static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]); + +                    unique_id[i] = (unsigned int)(unique_id[i] + serial_str[j]);                      j++;                  }              } -            VariantClear(&vtProp); +            return true; +        } +    } +    return false; +} +#endif -            pclsObj->Release(); -            pclsObj = NULL; -            break; +// get an unique machine id. +// NOT THREAD SAFE - do before setting up threads. +// MAC Address doesn't work for Windows 7 since the first returned hardware MAC address changes with each reboot,  Go figure?? + +S32 LLMachineID::init() +{ +    size_t len = sizeof(static_unique_id); +    memset(static_unique_id, 0, len); +    S32 ret_code = 0; +#if	LL_WINDOWS + +    LLWMIMethods comInit; + +    if (comInit.getWindowsProductNumber(static_legacy_id, len)) +    { +        // Bios id can change on windows update, so it is not the best id to use +        // but since old viewer already use them, we might need this id to decode +        // passwords +        has_static_legacy_id = true; +    } + +    // Try motherboard/bios id, if it is present it is supposed to be sufficiently unique +    if (comInit.getComputerSystemProductUUID(static_unique_id, len)) +    { +        has_static_unique_id = true; +        LL_DEBUGS("AppInit") << "Using product uuid as unique id" << LL_ENDL; +    } + +    // Fallback to legacy +    if (!has_static_unique_id) +    { +        if (has_static_legacy_id) +        { +            memcpy(static_unique_id, &static_legacy_id, len); +            // Since ids are identical, mark legacy as not present +            // to not cause retry's in sechandler +            has_static_legacy_id = false; +            has_static_unique_id = true; +            LL_DEBUGS("AppInit") << "Using legacy serial" << LL_ENDL; +        } +        else +        { +            return 1; // Program has failed.          } +    } -        // Cleanup -        // ======== -         -        if (pSvc) -            pSvc->Release(); -        if (pLoc) -            pLoc->Release(); -        if (pEnumerator) -            pEnumerator->Release(); -        ret_code=0; -#else -        unsigned char * staticPtr = (unsigned char *)(&static_unique_id[0]); +    ret_code=0; +#elif LL_DARWIN +    if (getSerialNumber(static_unique_id, len)) +    { +        has_static_unique_id = true; +        LL_DEBUGS("AppInit") << "Using Serial number as unique id" << LL_ENDL; +    } + +    { +        unsigned char * staticPtr = (unsigned char *)(&static_legacy_id[0]);          ret_code = LLUUID::getNodeID(staticPtr); +        has_static_legacy_id = true; +    } + +    // Fallback to legacy +    if (!has_static_unique_id) +    { +        if (has_static_legacy_id) +        { +            memcpy(static_unique_id, &static_legacy_id, len); +            // Since ids are identical, mark legacy as not present +            // to not cause retry's in sechandler +            has_static_legacy_id = false; +            has_static_unique_id = true; +            LL_DEBUGS("AppInit") << "Using legacy serial" << LL_ENDL; +        } +    } +#else +    unsigned char * staticPtr = (unsigned char *)(&static_legacy_id[0]); +    ret_code = LLUUID::getNodeID(staticPtr); +    has_static_unique_id = true; +    has_static_legacy_id = false;  #endif -        has_static_unique_id = true;          LL_INFOS("AppInit") << "UniqueID: 0x";          // Code between here and LL_ENDL is not executed unless the LL_DEBUGS @@ -292,3 +500,13 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)      }      return 0;  } + +S32 LLMachineID::getLegacyID(unsigned char *unique_id, size_t len) +{ +    if (has_static_legacy_id) +    { +        memcpy(unique_id, &static_legacy_id, len); +        return 1; +    } +    return 0; +} diff --git a/indra/newview/llmachineid.h b/indra/newview/llmachineid.h index 6ef8c36fdb..ec1e855031 100644 --- a/indra/newview/llmachineid.h +++ b/indra/newview/llmachineid.h @@ -34,6 +34,8 @@ public:  	LLMachineID();  	virtual	~LLMachineID();      static S32 getUniqueID(unsigned char *unique_id, size_t len); +    // fallback id for windows +    static S32 getLegacyID(unsigned char *unique_id, size_t len);      static S32 init();  protected: diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 272e7ae351..ca7bd8cb2c 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -893,7 +893,7 @@ void LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation(const LLSD& notifi  void LLOutfitGalleryContextMenu::onCreate(const LLSD& data)  { -    LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); +    LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(data.asString());      if (type == LLWearableType::WT_NONE)      {          LL_WARNS() << "Invalid wearable type" << LL_ENDL; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 71ab826e1c..a71432e314 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -1210,7 +1210,7 @@ void LLOutfitListGearMenuBase::onRename()  void LLOutfitListGearMenuBase::onCreate(const LLSD& data)  { -    LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); +    LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(data.asString());      if (type == LLWearableType::WT_NONE)      {          LL_WARNS() << "Invalid wearable type" << LL_ENDL; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index c601a6c210..be11a4a9f3 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1276,7 +1276,7 @@ void LLPanelEditWearable::changeCamera(U8 subpart)  {  	// Don't change the camera if this type doesn't have a camera switch.  	// Useful for wearables like physics that don't have an associated physical body part. -	if (LLWearableType::getDisableCameraSwitch(mWearablePtr->getType())) +	if (LLWearableType::getInstance()->getDisableCameraSwitch(mWearablePtr->getType()))  	{  		return;  	} diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp index 052212dc27..52be75072c 100644 --- a/indra/newview/llpanelgroupcreate.cpp +++ b/indra/newview/llpanelgroupcreate.cpp @@ -45,6 +45,7 @@  #include "llfloaterreg.h"  #include "llfloater.h"  #include "llgroupmgr.h" +#include "llstatusbar.h" // to re-request balance  #include "lltrans.h"  #include "llnotificationsutil.h"  #include "lluicolortable.h" @@ -117,6 +118,7 @@ void LLPanelGroupCreate::refreshCreatedGroup(const LLUUID& group_id)      params["group_id"] = group_id;      params["open_tab_name"] = "panel_group_info_sidetray";      LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params); +    LLStatusBar::sendMoneyBalanceRequest();  }  void LLPanelGroupCreate::addMembershipRow(const std::string &name) diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 28a020870f..984fb49c83 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -97,7 +97,7 @@ std::string LLShopURLDispatcher::resolveURL(LLWearableType::EType wearable_type,  {  	const std::string prefix = "MarketplaceURL";  	const std::string sex_str = (sex == SEX_MALE) ? "Male" : "Female"; -	const std::string type_str = LLWearableType::getTypeName(wearable_type); +	const std::string type_str = LLWearableType::getInstance()->getTypeName(wearable_type);  	std::string setting_name = prefix; @@ -173,7 +173,7 @@ public:  private:  	static void onCreate(const LLSD& param)  	{ -		LLWearableType::EType type = LLWearableType::typeNameToType(param.asString()); +		LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(param.asString());  		if (type == LLWearableType::WT_NONE)  		{  			LL_WARNS() << "Invalid wearable type" << LL_ENDL; @@ -188,19 +188,20 @@ private:  	{  		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);  		LLView* menu_bp			= gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE); +		LLWearableType * wearable_type_inst = LLWearableType::getInstance();  		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)  		{  			LLWearableType::EType type = (LLWearableType::EType) i; -			const std::string& type_name = LLWearableType::getTypeName(type); +			const std::string& type_name = wearable_type_inst->getTypeName(type);  			LLMenuItemCallGL::Params p;  			p.name = type_name; -			p.label = LLTrans::getString(LLWearableType::getTypeDefaultNewName(type)); +			p.label = LLTrans::getString(wearable_type_inst->getTypeDefaultNewName(type));  			p.on_click.function_name = "Wearable.Create";  			p.on_click.parameter = LLSD(type_name); -            LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp; +			LLView* parent = wearable_type_inst->getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;  			LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);  		}  	} diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 1b60610668..59be35fe92 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -232,6 +232,7 @@ void LLPreviewNotecard::loadAsset()  	if (!editor)  		return; +	bool fail = false;  	if(item)  	{ @@ -315,7 +316,31 @@ void LLPreviewNotecard::loadAsset()  			getChildView("Delete")->setEnabled(TRUE);  		}  	} -	else +    else if (mObjectUUID.notNull() && mItemUUID.notNull()) +    { +        LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); +        if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty())) +        { +            // It's a notecard in object's inventory and we failed to get it because inventory is not up to date. +            // Subscribe for callback and retry at inventoryChanged() +            registerVOInventoryListener(objectp, NULL); //removes previous listener + +            if (objectp->isInventoryDirty()) +            { +                objectp->requestInventory(); +            } +        } +        else +        { +            fail = true; +        } +    } +    else +    { +        fail = true; +    } + +	if (fail)  	{  		editor->setText(LLStringUtil::null);  		editor->makePristine(); @@ -600,6 +625,17 @@ void LLPreviewNotecard::syncExternal()  	}  } +/*virtual*/ +void LLPreviewNotecard::inventoryChanged(LLViewerObject* object, +    LLInventoryObject::object_list_t* inventory, +    S32 serial_num, +    void* user_data) +{ +    removeVOInventoryListener(); +    loadAsset(); +} + +  void LLPreviewNotecard::deleteNotecard()  {  	LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2)); diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index d9c14815c1..3a706b8645 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -31,6 +31,7 @@  #include "llassetstorage.h"  #include "llpreviewscript.h"  #include "lliconctrl.h" +#include "llvoinventorylistener.h"  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLPreviewNotecard @@ -41,7 +42,7 @@  class LLViewerTextEditor;  class LLButton; -class LLPreviewNotecard : public LLPreview +class LLPreviewNotecard : public LLPreview, public LLVOInventoryListener  {  public:  	LLPreviewNotecard(const LLSD& key); @@ -75,6 +76,11 @@ public:  	void syncExternal(); +    void inventoryChanged(LLViewerObject* object, +        LLInventoryObject::object_list_t* inventory, +        S32 serial_num, +        void* user_data) override; +  protected:  	void updateTitleButtons() override; diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 1e91da529c..53869606bb 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -50,6 +50,7 @@  #include "llviewertexture.h"  #include "llviewertexturelist.h"  #include "lluictrlfactory.h" +#include "llviewercontrol.h"  #include "llviewerwindow.h"  #include "lllineeditor.h" @@ -317,6 +318,44 @@ void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenam  		0, TRUE, FALSE, new LLUUID(mItemUUID), &mCallbackTextureList);  } + +void LLPreviewTexture::saveMultipleToFile() +{ +    std::string texture_location(gSavedSettings.getString("TextureSaveLocation"));	 +    std::string texture_name = getItem()->getName(); +     +    std::string filepath; +    S32 i = 0; +    S32 err = 0; +    std::string extension(".png"); +    do +    { +        filepath = texture_location; +        filepath += gDirUtilp->getDirDelimiter(); +        filepath += texture_name; + +        if (i != 0) +        { +            filepath += llformat("_%.3d", i); +        } + +        filepath += extension; + +        llstat stat_info; +        err = LLFile::stat( filepath, &stat_info ); +        i++; +    } while (-1 != err);  // Search until the file is not found (i.e., stat() gives an error). +     +     +    mSaveFileName = filepath; +    mLoadingFullImage = TRUE; +    getWindow()->incBusyCount(); + +    mImage->forceToSaveRawImage(0);//re-fetch the raw image if the old one is removed. +    mImage->setLoadedCallback(LLPreviewTexture::onFileLoadedForSave, +        0, TRUE, FALSE, new LLUUID(mItemUUID), &mCallbackTextureList); +} +  // virtual  void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)  { diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index ad77d9e118..cc6c7854b6 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -63,6 +63,7 @@ public:  	void 				openToSave();  	void				saveTextureToFile(const std::vector<std::string>& filenames); +    void                saveMultipleToFile();  	static void			onSaveAsBtn(void* data); diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp index 7daaa7ef8e..6caec6ec4a 100644 --- a/indra/newview/llregioninfomodel.cpp +++ b/indra/newview/llregioninfomodel.cpp @@ -173,6 +173,29 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)  		mRegionFlags = flags;  	} +	if (msg->has(_PREHASH_RegionInfo5)) +	{ +		F32 chat_whisper_range; +		F32 chat_normal_range; +		F32 chat_shout_range; +		F32 chat_whisper_offset; +		F32 chat_normal_offset; +		F32 chat_shout_offset; +		U32 chat_flags; + +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperRange, chat_whisper_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalRange, chat_normal_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutRange, chat_shout_range); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatWhisperOffset, chat_whisper_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatNormalOffset, chat_normal_offset); +		msg->getF32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatShoutOffset, chat_shout_offset); +		msg->getU32Fast(_PREHASH_RegionInfo5, _PREHASH_ChatFlags, chat_flags); + +		LL_INFOS() << "Whisper range: " << chat_whisper_range << " normal range: " << chat_normal_range << " shout range: " << chat_shout_range +			<< " whisper offset: " << chat_whisper_offset << " normal offset: " << chat_normal_offset << " shout offset: " << chat_shout_offset +			<< " chat flags: " << chat_flags << LL_ENDL; +	} +  	// the only reasonable way to decide if we actually have any data is to  	// check to see if any of these fields have nonzero sizes  	if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 || diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 737ef30ada..dcedf5858a 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -1302,8 +1302,8 @@ LLSecAPIBasicHandler::~LLSecAPIBasicHandler()  	_writeProtectedData();  } -void LLSecAPIBasicHandler::_readProtectedData() -{	 +void LLSecAPIBasicHandler::_readProtectedData(unsigned char *unique_id, U32 id_len) +{  	// attempt to load the file into our map  	LLPointer<LLSDParser> parser = new LLSDXMLParser();  	llifstream protected_data_stream(mProtectedDataFilename.c_str(),  @@ -1314,9 +1314,7 @@ void LLSecAPIBasicHandler::_readProtectedData()  		U8 buffer[BUFFER_READ_SIZE];  		U8 decrypted_buffer[BUFFER_READ_SIZE];  		int decrypted_length;	 -		unsigned char unique_id[MAC_ADDRESS_BYTES]; -        LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); -		LLXORCipher cipher(unique_id, sizeof(unique_id)); +		LLXORCipher cipher(unique_id, id_len);  		// read in the salt and key  		protected_data_stream.read((char *)salt, STORE_SALT_SIZE); @@ -1367,6 +1365,30 @@ void LLSecAPIBasicHandler::_readProtectedData()  	}  } +void LLSecAPIBasicHandler::_readProtectedData() +{ +    unsigned char unique_id[MAC_ADDRESS_BYTES]; +    try +    { +        // try default id +        LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); +        _readProtectedData(unique_id, sizeof(unique_id)); +    } +    catch(LLProtectedDataException&) +    { +        // try with legacy id, it will return false if it is identical to getUniqueID +        // or if it is not assigned/not in use +        if (LLMachineID::getLegacyID(unique_id, sizeof(unique_id))) +        { +            _readProtectedData(unique_id, sizeof(unique_id)); +        } +        else +        { +            throw; +        } +    } +} +  void LLSecAPIBasicHandler::_writeProtectedData()  {	  	std::ostringstream formatted_data_ostream; diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h index 0bc7f5230f..b21a5d08f9 100644 --- a/indra/newview/llsechandler_basic.h +++ b/indra/newview/llsechandler_basic.h @@ -326,6 +326,7 @@ public:  protected: +	void _readProtectedData(unsigned char *unique_id, U32 id_len);  	void _readProtectedData();  	void _writeProtectedData();  	std::string _legacyLoadPassword(); diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 48151c17ea..1158f3c5dc 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -206,7 +206,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  			// when editing its physics.  			if (!gAgentCamera.cameraCustomizeAvatar())  			{ -				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType())); +				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getInstance()->getDisableCameraSwitch(wearable_ptr->getType()));  			}  			if (is_wearable_edit_visible)  			{ diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 864ce09430..f98f9c69f2 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1109,8 +1109,6 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l  				final_name = LLTrans::getString("TooltipPerson");;  			} -			// *HACK: We may select this object, so pretend it was clicked -			mPick = mHoverPick;  			LLInspector::Params p;  			p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());  			p.message(final_name); @@ -1222,8 +1220,6 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l  			if (show_all_object_tips || needs_tip)  			{ -				// We may select this object, so pretend it was clicked -				mPick = mHoverPick;  				LLInspector::Params p;  				p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());  				p.message(tooltip_msg); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 8aa5b07561..6363edfb36 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -143,6 +143,20 @@ static bool handleSetShaderChanged(const LLSD& newvalue)  	gBumpImageList.destroyGL();  	gBumpImageList.restoreGL(); +    if (gPipeline.isInit()) +    { +        // ALM depends onto atmospheric shaders, state might have changed +        bool old_state = LLPipeline::sRenderDeferred; +        LLPipeline::refreshCachedSettings(); +        gPipeline.updateRenderDeferred(); +        if (old_state != LLPipeline::sRenderDeferred) +        { +            gPipeline.releaseGLBuffers(); +            gPipeline.createGLBuffers(); +            gPipeline.resetVertexBuffers(); +        } +    } +  	// else, leave terrain detail as is  	LLViewerShaderMgr::instance()->setShaders();  	return true; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index bbed741a33..55ac817479 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1756,7 +1756,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,  	else  	{  		// Use for all clothing and body parts.  Adding new wearable types requires updating LLWearableDictionary. -		LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name); +		LLWearableType::EType wearable_type = LLWearableType::getInstance()->typeNameToType(type_name);  		if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT)  		{  			const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0404a8056a..a89e570e88 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8478,7 +8478,7 @@ class LLEditEnableTakeOff : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{  		std::string clothing = userdata.asString(); -		LLWearableType::EType type = LLWearableType::typeNameToType(clothing); +		LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);  		if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT)  			return LLAgentWearables::selfHasWearable(type);  		return false; @@ -8494,7 +8494,7 @@ class LLEditTakeOff : public view_listener_t  			LLAppearanceMgr::instance().removeAllClothesFromAvatar();  		else  		{ -			LLWearableType::EType type = LLWearableType::typeNameToType(clothing); +			LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);  			if (type >= LLWearableType::WT_SHAPE   				&& type < LLWearableType::WT_COUNT  				&& (gAgentWearables.getWearableCount(type) > 0)) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2fde4fe49c..d337f2fb6d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2807,7 +2807,6 @@ void LLViewerRegion::unpackRegionHandshake()  		mProductName = productName;  	} -  	mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");  	LLVLComposition *compp = getComposition();  	if (compp) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index be5c22e7c3..945b51d819 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -466,8 +466,8 @@ void LLViewerShaderMgr::setShaders()      bool canRenderDeferred       = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");      bool hasWindLightShaders     = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");      S32 shadow_detail            = gSavedSettings.getS32("RenderShadowDetail"); -    bool useRenderDeferred       = canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP");      bool doingWindLight          = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders"); +    bool useRenderDeferred       = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP");      //using shaders, disable fixed function      LLGLSLShader::sNoFixedFunction = true; diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index 9c4dfd1ca2..c80cf27bda 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -562,7 +562,7 @@ void LLViewerWearable::saveNewAsset() const  void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)  {  	LLWearableSaveData* data = (LLWearableSaveData*)userdata; -	const std::string& type_name = LLWearableType::getTypeName(data->mType); +	const std::string& type_name = LLWearableType::getInstance()->getTypeName(data->mType);  	if(0 == status)  	{  		// Success @@ -588,7 +588,7 @@ void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void*  std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)  { -	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n"; +	s << "wearable " << LLWearableType::getInstance()->getTypeName(w.mType) << "\n";  	s << "    Name: " << w.mName << "\n";  	s << "    Desc: " << w.mDescription << "\n";  	//w.mPermissions diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f69b9b3861..1a26308b60 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8952,7 +8952,7 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)  	S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());  	apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n",  					viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(), -					LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str(), +					LLWearableType::getInstance()->getTypeName(LLWearableType::EType(wtype)).c_str(),  					viewer_param->getGroup());  	} @@ -9730,6 +9730,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  	std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");  	LLAPRFile outfile; +    LLWearableType *wr_inst = LLWearableType::getInstance();  	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);  	if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB ))  	{ @@ -9746,7 +9747,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  		{  			for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)  			{ -				const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type); +				const std::string& wearable_name = wr_inst->getTypeName((LLWearableType::EType)type);  				apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );  				for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam()) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 458d8ced65..6a7bdc7f56 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2030,6 +2030,7 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini  const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const  {  	std::ostringstream outbuf; +    LLWearableType *wr_inst = LLWearableType::getInstance();  	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =  			 sAvatarDictionary->getBakedTextures().begin();  		 baked_iter != sAvatarDictionary->getBakedTextures().end(); @@ -2053,7 +2054,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV  				{  					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)  					{ -						outbuf << "    " << LLWearableType::getTypeName(wearable_type) << " " << wearable_index << ":"; +						outbuf << "    " << wr_inst->getTypeName(wearable_type) << " " << wearable_index << ":";  						const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);  						if (local_tex_obj)  						{ @@ -2108,6 +2109,7 @@ void LLVOAvatarSelf::dumpAllTextures() const  const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const  {  	std::string text=""; +    LLWearableType *wr_inst = LLWearableType::getInstance();  	text = llformat("[Final:%d Avail:%d] ",isLocalTextureDataFinal(layerset), isLocalTextureDataAvailable(layerset)); @@ -2131,7 +2133,7 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTe  				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);  				if (wearable_count > 0)  				{ -					text += LLWearableType::getTypeName(wearable_type) + ":"; +					text += wr_inst->getTypeName(wearable_type) + ":";  					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)  					{  						const U32 discard_level = getLocalDiscardLevel(tex_index, wearable_index); @@ -2838,9 +2840,10 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)  	apr_file_printf( file, "\n<wearable_info>\n" );  	LLWearableData *wd = getWearableData(); +    LLWearableType *wr_inst = LLWearableType::getInstance();  	for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)  	{ -		const std::string& type_name = LLWearableType::getTypeName((LLWearableType::EType)type); +		const std::string& type_name = wr_inst->getTypeName((LLWearableType::EType)type);  		for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)  		{  			LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 9acc0f8d2f..a5b81d92e6 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -1005,7 +1005,7 @@ void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu)  	if (!item || !item->isWearableType()) return;  	LLWearableType::EType w_type = item->getWearableType(); -	std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type)); +	std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getInstance()->getTypeName(w_type));  	LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new");  	menu_item->setLabel(new_label); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index b61fbbd073..00f8bace70 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -241,7 +241,7 @@ LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type,  	LLViewerWearable *wearable = generateNewWearable();  	wearable->setType( type, avatarp ); -	std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) ); +	std::string name = LLWearableType::getInstance()->getTypeLabel(wearable->getType());  	wearable->setName( name );  	LLPermissions perm; diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index eda9739976..0f790bf26a 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -807,6 +807,14 @@           function="Inventory.DoToSelected"           parameter="save_as" />      </menu_item_call> +  <menu_item_call + label="Save Selected As" + layout="topleft" + name="Save Selected As"> +    <menu_item_call.on_click +     function="Inventory.DoToSelected" +     parameter="save_selected_as" /> +  </menu_item_call>      <menu_item_separator       layout="topleft"        name="Wearable And Object Separator"/> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 57f2d31eab..ba85729b87 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -302,6 +302,10 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)  	memcpy(unique_id, gMACAddress, len);  	return 1;  } +S32 LLMachineID::getLegacyID(unsigned char *unique_id, size_t len) +{ +    return 0; +}  //-----------------------------------------------------------------------------  // misc  std::string xml_escape_string(const std::string& in) diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index e5d226a2a4..02185316b2 100644 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -121,6 +121,10 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)  	memcpy(unique_id, gMACAddress, len);  	return 1;  } +S32 LLMachineID::getLegacyID(unsigned char *unique_id, size_t len) +{ +    return 0; +}  S32 LLMachineID::init() { return 1; } diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 635227ccf3..a3ddc6d336 100755 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -2999,6 +2999,16 @@ version 2.0  		RegionInfo3		Variable  		{	RegionFlagsExtended	U64			}  	} +	{ +		RegionInfo5     Variable +		{	ChatWhisperRange	F32 		} +		{	ChatNormalRange		F32 		} +		{	ChatShoutRange		F32 		} +		{	ChatWhisperOffset	F32 		} +		{	ChatNormalOffset	F32 		} +		{	ChatShoutOffset		F32 		} +		{	ChatFlags			U32			} +	}  }  // GodUpdateRegionInfo diff --git a/scripts/template_verifier.py b/scripts/template_verifier.py index b44410cdd8..358931b13e 100755 --- a/scripts/template_verifier.py +++ b/scripts/template_verifier.py @@ -229,7 +229,7 @@ http://wiki.secondlife.com/wiki/Template_verifier.py  """)      parser.add_option(          '-u', '--master_url', type='string', dest='master_url', -        default='http://bitbucket.org/lindenlab/master-message-template/raw/tip/message_template.msg', +        default='https://bitbucket.org/lindenlab/master-message-template-git/raw/master/message_template.msg',          help="""The url of the master message template.""")      parser.add_option(          '-c', '--cache_master', action='store_true', dest='cache_master',  | 
