diff options
149 files changed, 1134 insertions, 235 deletions
| diff --git a/etc/message.xml b/etc/message.xml index dd1fda059e..7ad392d0b5 100644 --- a/etc/message.xml +++ b/etc/message.xml @@ -668,6 +668,9 @@  			<key>FetchLib</key>  			<boolean>true</boolean> + +			<key>UploadBakedTexture</key> +			<boolean>true</boolean>  		</map>  		<key>messageBans</key> diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake new file mode 100644 index 0000000000..ca5a8034ba --- /dev/null +++ b/indra/cmake/GoogleMock.cmake @@ -0,0 +1,27 @@ +# -*- cmake -*- +include(Prebuilt) +include(Linking) + +use_prebuilt_binary(googlemock) + +set(GOOGLEMOCK_INCLUDE_DIRS  +    ${LIBS_PREBUILT_DIR}/include) + +if (LINUX) +    set(GOOGLEMOCK_LIBRARIES  +        gmock   +        gtest) +elseif(WINDOWS) +    set(GOOGLEMOCK_LIBRARIES  +        gmock) +    set(GOOGLEMOCK_INCLUDE_DIRS  +        ${LIBS_PREBUILT_DIR}/include +        ${LIBS_PREBUILT_DIR}/include/gmock +        ${LIBS_PREBUILT_DIR}/include/gmock/boost/tr1/tr1) +elseif(DARWIN) +    set(GOOGLEMOCK_LIBRARIES +        gmock +        gtest) +endif(LINUX) + + diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 7d6ef9ab1a..373ad4d4e9 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -13,6 +13,8 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)    #    # WARNING: do NOT modify this code without working with poppy or daveh -    # there is another branch that will conflict heavily with any changes here. +INCLUDE(GoogleMock) +    IF(LL_TEST_VERBOSE)      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") @@ -32,8 +34,10 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)      ${LLMATH_INCLUDE_DIRS}      ${LLCOMMON_INCLUDE_DIRS}      ${LIBS_OPEN_DIR}/test +    ${GOOGLEMOCK_INCLUDE_DIRS}      )    SET(alltest_LIBRARIES +    ${GOOGLEMOCK_LIBRARIES}      ${PTHREAD_LIBRARY}      ${WINDOWS_LIBRARIES}      ) @@ -42,6 +46,11 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)      ${CMAKE_SOURCE_DIR}/test/test.h      ) +  # Use the default flags +  if (LINUX) +    SET(CMAKE_EXE_LINKER_FLAGS "") +  endif (LINUX) +    # start the source test executable definitions    SET(${project}_TEST_OUTPUT "")    FOREACH (source ${sources}) @@ -84,9 +93,9 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)        MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")      ENDIF(LL_TEST_VERBOSE) +      # Setup target      ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) -      #      # Per-codefile additional / external project dep and lib dep property extraction      # diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py index 1190d88663..4527b115f9 100644 --- a/indra/lib/python/indra/base/llsd.py +++ b/indra/lib/python/indra/base/llsd.py @@ -238,7 +238,7 @@ class LLSDXMLFormatter(object):      def MAP(self, v):          return self.elt(              'map', -            ''.join(["%s%s" % (self.elt('key', key), self.generate(value)) +            ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value))               for key, value in v.items()]))      typeof = type diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py index aceea29cd2..1cdd8e915b 100644 --- a/indra/lib/python/indra/base/lluuid.py +++ b/indra/lib/python/indra/base/lluuid.py @@ -26,8 +26,14 @@ THE SOFTWARE.  $/LicenseInfo$  """ -import md5, random, socket, string, time, re +import random, socket, string, time, re  import uuid +try: +    # Python 2.6 +    from hashlib import md5 +except ImportError: +    # Python 2.5 and earlier +    from md5 import new as md5  def _int2binstr(i,l):      s='' @@ -196,7 +202,7 @@ class UUID(object):          from c++ implementation for portability reasons.          Returns self.          """ -        m = md5.new() +        m = md5()          m.update(uuid.uuid1().bytes)          self._bits = m.digest()          return self diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py index c4c40739ec..7e0e115d14 100644 --- a/indra/lib/python/indra/util/llsubprocess.py +++ b/indra/lib/python/indra/util/llsubprocess.py @@ -90,6 +90,17 @@ all the output, and get the result.                      child.tochild.close()          result = child.poll()          if result != -1: +            # At this point, the child process has exited and result +            # is the return value from the process. Between the time +            # we called select() and poll() the process may have +            # exited so read all the data left on the child process +            # stdout and stderr. +            last = child.fromchild.read() +            if last: +                out.append(last) +            last = child.childerr.read() +            if last: +                err.append(last)              child.tochild.close()              child.fromchild.close()              child.childerr.close() diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py index 693b483f79..5c19368240 100644 --- a/indra/lib/python/indra/util/named_query.py +++ b/indra/lib/python/indra/util/named_query.py @@ -48,8 +48,8 @@ from indra.base import llsd  from indra.base import config  DEBUG = False -NQ_FILE_SUFFIX = None -NQ_FILE_SUFFIX_LEN = None +NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq') +NQ_FILE_SUFFIX_LEN  = len(NQ_FILE_SUFFIX)  _g_named_manager = None diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp index 1d42298f4d..1ae0ddeea0 100644 --- a/indra/llcharacter/llkeyframestandmotion.cpp +++ b/indra/llcharacter/llkeyframestandmotion.cpp @@ -190,7 +190,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)  	if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD)  	{  		mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation(); -		mLastGoodPelvisRotation.normQuat(); +		mLastGoodPelvisRotation.normalize();  		mTrackAnkles = TRUE;  	}  	else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index bc4e44d7e6..6a97446a50 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -240,7 +240,7 @@ SET(llcommon_TEST_SOURCE_FILES  LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}")  #set(TEST_DEBUG on) -set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) +set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES} gmock gtest)  # Have to treat lllazy test as an integration test until this issue is resolved:  # https://jira.lindenlab.com/jira/browse/DEV-29456  LL_ADD_INTEGRATION_TEST(lllazy lllazy.cpp "${test_libs}") diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e595cc1f8b..66c8bcac6a 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -289,6 +289,7 @@ bool LLAssetType::lookupIsEnsembleCategoryType(EType asset_type)  			asset_type <= AT_FOLDER_ENSEMBLE_END);  } +  // static. Generate a good default description  void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type,  										 std::string& description) diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 5e51188541..880b7a19b5 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -150,6 +150,7 @@ public:  		AT_COUNT = 49, +  			// +*********************************************************+  			// |  TO ADD AN ELEMENT TO THIS ENUM:                        |  			// +*********************************************************+ diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h index 873f50a65e..7544ab1d11 100644 --- a/indra/llcommon/llkeythrottle.h +++ b/indra/llcommon/llkeythrottle.h @@ -118,6 +118,63 @@ public:  		THROTTLE_BLOCKED,		// rate exceed, block key  	}; +	F64 getActionCount(const T& id) +	{ +		U64 now = 0; +		if ( mIsRealtime ) +		{ +			now = LLKeyThrottleImpl<T>::getTime(); +		} +		else +		{ +			now = LLKeyThrottleImpl<T>::getFrame(); +		} + +		if (now >= (m.startTime + m.intervalLength)) +		{ +			if (now < (m.startTime + 2 * m.intervalLength)) +			{ +				// prune old data +				delete m.prevMap; +				m.prevMap = m.currMap; +				m.currMap = new typename LLKeyThrottleImpl<T>::EntryMap; + +				m.startTime += m.intervalLength; +			} +			else +			{ +				// lots of time has passed, all data is stale +				delete m.prevMap; +				delete m.currMap; +				m.prevMap = new typename LLKeyThrottleImpl<T>::EntryMap; +				m.currMap = new typename LLKeyThrottleImpl<T>::EntryMap; + +				m.startTime = now; +			} +		} + +		U32 prevCount = 0; + +		typename LLKeyThrottleImpl<T>::EntryMap::const_iterator prev = m.prevMap->find(id); +		if (prev != m.prevMap->end()) +		{ +			prevCount = prev->second.count; +		} + +		typename LLKeyThrottleImpl<T>::Entry& curr = (*m.currMap)[id]; + +		// curr.count is the number of keys in +		// this current 'time slice' from the beginning of it until now +		// prevCount is the number of keys in the previous +		// time slice scaled to be one full time slice back from the current  +		// (now) time. + +		// compute current, windowed rate +		F64 timeInCurrent = ((F64)(now - m.startTime) / m.intervalLength); +		F64 averageCount = curr.count + prevCount * (1.0 - timeInCurrent); +		return averageCount; +	} +  	// call each time the key wants use  	State noteAction(const T& id, S32 weight = 1)  	{ diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 90dae11793..0bd2609f4a 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -43,7 +43,7 @@  // statics -BOOL            LLPerfBlock::sStatsEnabled = FALSE;    // Flag for detailed information +S32	            LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS;       // Control what is being recorded  LLPerfBlock::stat_map_t    LLPerfBlock::sStatMap;    // Map full path string to LLStatTime objects, tracks all active objects  std::string        LLPerfBlock::sCurrentStatPath = "";    // Something like "/total_time/physics/physics step"  LLStat::stat_map_t LLStat::sStatList; @@ -130,6 +130,7 @@ bool LLStatsConfigFile::loadFile()      F32 duration = 0.f;      F32 interval = 0.f; +	S32 flags = LLPerfBlock::LLSTATS_BASIC_STATS;      const char * w = "duration";      if (stats_config.has(w)) @@ -141,8 +142,18 @@ bool LLStatsConfigFile::loadFile()      {          interval = (F32)stats_config[w].asReal();      }  +    w = "flags"; +    if (stats_config.has(w)) +    { +		flags = (S32)stats_config[w].asInteger(); +		if (flags == LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS && +			duration > 0) +		{   // No flags passed in, but have a duration, so reset to basic stats +			flags = LLPerfBlock::LLSTATS_BASIC_STATS; +		} +    }  -    mStatsp->setReportPerformanceDuration( duration ); +    mStatsp->setReportPerformanceDuration( duration, flags );      mStatsp->setReportPerformanceInterval( interval );      if ( duration > 0 ) @@ -254,13 +265,14 @@ void LLPerfStats::dumpIntervalPerformanceStats()      }  } -// Set length of performance stat recording -void    LLPerfStats::setReportPerformanceDuration( F32 seconds ) +// Set length of performance stat recording.   +// If turning stats on, caller must provide flags +void    LLPerfStats::setReportPerformanceDuration( F32 seconds, S32 flags /* = LLSTATS_NO_OPTIONAL_STATS */ )  {   	if ( seconds <= 0.f )  	{  		mReportPerformanceStatEnd = 0.0; -		LLPerfBlock::setStatsEnabled( FALSE ); +		LLPerfBlock::setStatsFlags(LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS);		// Make sure all recording is off  		mFrameStatsFile.close();  		LLPerfBlock::clearDynamicStats();  	} @@ -269,8 +281,8 @@ void    LLPerfStats::setReportPerformanceDuration( F32 seconds )  		mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds);  		// Clear failure flag to try and create the log file once  		mFrameStatsFileFailure = FALSE; -		LLPerfBlock::setStatsEnabled( TRUE );  		mSkipFirstFrameStats = TRUE;		// Skip the first report (at the end of this frame) +		LLPerfBlock::setStatsFlags(flags);  	}  } @@ -612,11 +624,26 @@ LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicSta      }  } -// Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key. -// These are also turned on or off via the switch passed in -LLPerfBlock::LLPerfBlock( const char* key1, const char* key2 ) : mPredefinedStat(NULL), mDynamicStat(NULL) +// Use this constructor for normal, optional LLPerfBlock time slices +LLPerfBlock::LLPerfBlock( const char* key ) : mPredefinedStat(NULL), mDynamicStat(NULL)  { -    if (!sStatsEnabled) return; +    if ((sStatsFlags & LLSTATS_BASIC_STATS) == 0) +	{	// These are off unless the base set is enabled +		return; +	} + +	initDynamicStat(key); +} + +	 +// Use this constructor for dynamically created LLPerfBlock time slices +// that are only enabled by specific control flags +LLPerfBlock::LLPerfBlock( const char* key1, const char* key2, S32 flags ) : mPredefinedStat(NULL), mDynamicStat(NULL) +{ +    if ((sStatsFlags & flags) == 0) +	{ +		return; +	}      if (NULL == key2 || strlen(key2) == 0)      { @@ -630,10 +657,12 @@ LLPerfBlock::LLPerfBlock( const char* key1, const char* key2 ) : mPredefinedStat      }  } +// Set up the result data map if dynamic stats are enabled  void LLPerfBlock::initDynamicStat(const std::string& key)  {      // Early exit if dynamic stats aren't enabled. -    if (!sStatsEnabled) return; +    if (sStatsFlags == LLSTATS_NO_OPTIONAL_STATS)  +		return;      mLastPath = sCurrentStatPath;		// Save and restore current path      sCurrentStatPath += "/" + key;		// Add key to current path diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index bad18f46a0..76aa3963f4 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -192,14 +192,23 @@ public:  	// Use this constructor for pre-defined LLStatTime objects  	LLPerfBlock(LLStatTime* stat); -	// Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key -	LLPerfBlock( const char* key1, const char* key2 = NULL); +	// Use this constructor for normal, optional LLPerfBlock time slices +	LLPerfBlock( const char* key ); +	// Use this constructor for dynamically created LLPerfBlock time slices +	// that are only enabled by specific control flags +	LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );  	~LLPerfBlock(); -	static void setStatsEnabled( BOOL enable )		{ sStatsEnabled = enable;	}; -	static S32  getStatsEnabled()					{ return sStatsEnabled;		}; +	enum +	{	// Stats bitfield flags +		LLSTATS_NO_OPTIONAL_STATS	= 0x00,		// No optional stats gathering, just pre-defined LLStatTime objects +		LLSTATS_BASIC_STATS			= 0x01,		// Gather basic optional runtime stats +		LLSTATS_SCRIPT_FUNCTIONS	= 0x02,		// Include LSL function calls +	}; +	static void setStatsFlags( S32 flags )	{ sStatsFlags = flags;	}; +	static S32  getStatsFlags()				{ return sStatsFlags;	};  	static void clearDynamicStats();		// Reset maps to clear out dynamic objects  	static void addStatsToLLSDandReset( LLSD & stats,		// Get current information and clear time bin @@ -213,7 +222,7 @@ private:  	LLStatTime * 			mPredefinedStat;		// LLStatTime object to get data  	StatEntry *				mDynamicStat;   		// StatEntryobject to get data -	static BOOL				sStatsEnabled;			// Normally FALSE +	static S32				sStatsFlags;			// Control what is being recorded      static stat_map_t		sStatMap;				// Map full path string to LLStatTime objects  	static std::string		sCurrentStatPath;		// Something like "frame/physics/physics step"  }; @@ -236,7 +245,7 @@ public:      BOOL    frameStatsIsRunning()                                { return (mReportPerformanceStatEnd > 0.);        };      F32     getReportPerformanceInterval() const                { return mReportPerformanceStatInterval;        };      void    setReportPerformanceInterval( F32 interval )        { mReportPerformanceStatInterval = interval;    }; -    void    setReportPerformanceDuration( F32 seconds ); +    void    setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );      void    setProcessName(const std::string& process_name) { mProcessName = process_name; }      void    setProcessPID(S32 process_pid) { mProcessPID = process_pid; } diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index e9e21cffb6..f073bd327b 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -34,7 +34,7 @@  #define LL_LLVERSIONSERVER_H  const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 29; +const S32 LL_VERSION_MINOR = 31;  const S32 LL_VERSION_PATCH = 0;  const S32 LL_VERSION_BUILD = 2425; diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h index 79a536a224..5ad230d1d5 100644 --- a/indra/llcommon/metapropertyt.h +++ b/indra/llcommon/metapropertyt.h @@ -94,6 +94,13 @@ inline const LLReflective* LLMetaPropertyT<LLUUID>::get(const LLReflective* obje  }  template <> +inline const LLReflective* LLMetaPropertyT<bool>::get(const LLReflective* object) const +{ +	checkObjectClass(object); +	return NULL; +} + +template <>  inline LLSD LLMetaPropertyT<S32>::getLLSD(const LLReflective* object) const  {  	return *(getProperty(object)); @@ -111,6 +118,12 @@ inline LLSD LLMetaPropertyT<LLUUID>::getLLSD(const LLReflective* object) const  	return *(getProperty(object));  } +template <> +inline LLSD LLMetaPropertyT<bool>::getLLSD(const LLReflective* object) const +{ +	return *(getProperty(object)); +} +  template<class TObject, class TProperty>  class LLMetaPropertyTT : public LLMetaPropertyT<TProperty>  { diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 363486fb9c..2352c8edd7 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -178,8 +178,8 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  							mMaxBytes(0),  							mRawDiscardLevel(-1),  							mRate(0.0f), -							mReversible(FALSE) -	 +							mReversible(FALSE), +							mAreaUsedForDataSizeCalcs(0)  {  	//We assume here that if we wanted to create via  	//a dynamic library that the approriate open calls were made @@ -195,6 +195,12 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  	}  	mImpl = j2cimpl_create_func(); + +	// Clear data size table +	for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++) +	{	// Array size is MAX_DISCARD_LEVEL+1 +		mDataSizes[i] = 0; +	}  }  // virtual @@ -367,9 +373,45 @@ S32 LLImageJ2C::calcHeaderSize()  	return calcHeaderSizeJ2C();  } + +// calcDataSize() returns how many bytes to read  +// to load discard_level (including header and higher discard levels)  S32 LLImageJ2C::calcDataSize(S32 discard_level)  { -	return calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), discard_level, mRate); +	discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); + +	if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())  +		|| mDataSizes[0] == 0) +	{ +		mAreaUsedForDataSizeCalcs = getHeight() * getWidth(); +		 +		S32 level = MAX_DISCARD_LEVEL;	// Start at the highest discard +		while ( level >= 0 ) +		{ +			mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); +			level--; +		} + +		/* This is technically a more correct way to calculate the size required +		   for each discard level, since they should include the size needed for +		   lower levels.   Unfortunately, this doesn't work well and will lead to  +		   download stalls.  The true correct way is to parse the header.  This will +		   all go away with http textures at some point. + +		// Calculate the size for each discard level.   Lower levels (higher quality) +		// contain the cumulative size of higher levels		 +		S32 total_size = calcHeaderSizeJ2C(); + +		S32 level = MAX_DISCARD_LEVEL;	// Start at the highest discard +		while ( level >= 0 ) +		{	// Add in this discard level and all before it +			total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); +			mDataSizes[level] = total_size; +			level--; +		} +		*/ +	} +	return mDataSizes[discard_level];  }  S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes) diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 23f6ef5fd1..55df7f4429 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -87,6 +87,10 @@ protected:  	void updateRawDiscardLevel();  	S32 mMaxBytes; // Maximum number of bytes of data to use... +	 +	S32 mDataSizes[MAX_DISCARD_LEVEL+1];		// Size of data required to reach a given level +	U32 mAreaUsedForDataSizeCalcs;				// Height * width used to calculate mDataSizes +  	S8  mRawDiscardLevel;  	F32 mRate;  	BOOL mReversible; diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index e2a77f1d1e..5d3fbe5128 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -458,6 +458,39 @@ void LLInventoryItem::setCreationDate(time_t creation_date_utc)  	mCreationDate = creation_date_utc;  } +void LLInventoryItem::accumulatePermissionSlamBits(const LLInventoryItem& old_item) +{ +	// Remove any pre-existing II_FLAGS_PERM_OVERWRITE_MASK flags  +	// because we now detect when they should be set. +	setFlags( old_item.getFlags() | (getFlags() & ~(LLInventoryItem::II_FLAGS_PERM_OVERWRITE_MASK)) ); + +	// Enforce the PERM_OVERWRITE flags for any masks that are different +	// but only for AT_OBJECT's since that is the only asset type that can  +	// exist in-world (instead of only in-inventory or in-object-contents). +	if (LLAssetType::AT_OBJECT == getType()) +	{ +		LLPermissions old_permissions = old_item.getPermissions(); +		U32 flags_to_be_set = 0; +		if(old_permissions.getMaskNextOwner() != getPermissions().getMaskNextOwner()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_SLAM_PERM; +		} +		if(old_permissions.getMaskEveryone() != getPermissions().getMaskEveryone()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; +		} +		if(old_permissions.getMaskGroup() != getPermissions().getMaskGroup()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; +		} +		LLSaleInfo old_sale_info = old_item.getSaleInfo(); +		if(old_sale_info != getSaleInfo()) +		{ +			flags_to_be_set |= LLInventoryItem::II_FLAGS_OBJECT_SLAM_SALE; +		} +		setFlags(getFlags() | flags_to_be_set); +	} +}  const LLSaleInfo& LLInventoryItem::getSaleInfo() const  { diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 2b4d8ed831..32f19d6be5 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -93,7 +93,6 @@ public:  	virtual const LLUUID& getUUID() const;  	const LLUUID& getParentUUID() const;  	virtual const LLUUID& getLinkedUUID() const; // get the inventoryID that this item points to, else this item's inventoryID -  	virtual const std::string& getName() const;  	virtual LLAssetType::EType getType() const;  	LLAssetType::EType getActualType() const; // bypasses indirection for linked items @@ -263,6 +262,10 @@ public:  	void setInventoryType(LLInventoryType::EType inv_type);  	void setFlags(U32 flags);  	void setCreationDate(time_t creation_date_utc); + +	// Check for changes in permissions masks and sale info +	// and set the corresponding bits in mFlags +	void accumulatePermissionSlamBits(const LLInventoryItem& old_item);  	// This is currently only used in the Viewer to handle calling cards  	// where the creator is actually used to store the target. diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index aa8391230c..2a9a596912 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -136,9 +136,9 @@ class LLSD;  class LLAccessEntry  {  public: -	LLUUID		mID; -	S32			mTime; -	U32			mFlags; +	LLUUID		mID;		// Agent ID +	S32			mTime;		// Time (unix seconds) when entry expires +	U32			mFlags;		// Not used - currently should always be zero  };  typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 0babf26457..d2e5034734 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -288,6 +288,17 @@ BOOL LLPermissions::setOwnerAndGroup(  	return allowed;  } +//Fix for DEV-33917, last owner isn't used much and has little impact on +//permissions so it's reasonably safe to do this, however, for now,  +//limiting the functionality of this routine to objects which are  +//group owned. +void LLPermissions::setLastOwner(const LLUUID& last_owner) +{ +	if (isGroupOwned()) +		mLastOwner = last_owner; +} + +   // only call this if you know what you're doing  // there are usually perm-bit consequences when the   // ownerhsip changes @@ -895,6 +906,8 @@ void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)  {  	reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);  	reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner); +	reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup); +	reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned);  }  // virtual diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 864088148f..d5a0881c8f 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -232,6 +232,10 @@ public:  	// ownerhsip changes  	void yesReallySetOwner(const LLUUID& owner, bool group_owned); +	// Last owner doesn't have much in the way of permissions so it's  +	//not too dangerous to do this.  +	void setLastOwner(const LLUUID& last_owner); +  	// saves last owner, sets owner to uuid null, sets group  	// owned. group_id must be the group of the object (that's who it  	// is being deeded to) and the object must be group diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index cfd6183ec4..fdcc19d657 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -121,7 +121,7 @@ void	LLQuaternion::quantize16(F32 lower, F32 upper)  	mQ[VZ] = z;  	mQ[VS] = s; -	normQuat(); +	normalize();  }  void	LLQuaternion::quantize8(F32 lower, F32 upper) @@ -131,7 +131,7 @@ void	LLQuaternion::quantize8(F32 lower, F32 upper)  	mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);  	mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper); -	normQuat(); +	normalize();  }  // LLVector3 Magnitude and Normalization Functions @@ -346,7 +346,7 @@ const LLQuaternion&	LLQuaternion::setQuat(const LLMatrix4 &mat)  //    mQ[VZ] = (F32)(cosX*cosY*sinZ - sinX*sinY*cosZ);  //#endif  // -//	normQuat(); +//	normalize();  //	return (*this);  } diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index 5db9c5be2e..0769f29f23 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -469,20 +469,30 @@ inline const LLQuaternion&	operator*=(LLQuaternion &a, const LLQuaternion &b)  	return a;  } +const F32 ONE_PART_IN_A_MILLION = 0.000001f; +  inline F32	LLQuaternion::normalize()  {  	F32 mag = sqrtf(mQ[VX]*mQ[VX] + mQ[VY]*mQ[VY] + mQ[VZ]*mQ[VZ] + mQ[VS]*mQ[VS]);  	if (mag > FP_MAG_THRESHOLD)  	{ -		F32 oomag = 1.f/mag; -		mQ[VX] *= oomag; -		mQ[VY] *= oomag; -		mQ[VZ] *= oomag; -		mQ[VS] *= oomag; +		// Floating point error can prevent some quaternions from achieving +		// exact unity length.  When trying to renormalize such quaternions we +		// can oscillate between multiple quantized states.  To prevent such +		// drifts we only renomalize if the length is far enough from unity. +		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +		{ +			F32 oomag = 1.f/mag; +			mQ[VX] *= oomag; +			mQ[VY] *= oomag; +			mQ[VZ] *= oomag; +			mQ[VS] *= oomag; +		}  	}  	else  	{ +		// we were given a very bad quaternion so we set it to identity  		mQ[VX] = 0.f;  		mQ[VY] = 0.f;  		mQ[VZ] = 0.f; @@ -499,11 +509,15 @@ inline F32	LLQuaternion::normQuat()  	if (mag > FP_MAG_THRESHOLD)  	{ -		F32 oomag = 1.f/mag; -		mQ[VX] *= oomag; -		mQ[VY] *= oomag; -		mQ[VZ] *= oomag; -		mQ[VS] *= oomag; +		if (fabs(1.f - mag) > ONE_PART_IN_A_MILLION) +		{ +			// only renormalize if length not close enough to 1.0 already +			F32 oomag = 1.f/mag; +			mQ[VX] *= oomag; +			mQ[VY] *= oomag; +			mQ[VZ] *= oomag; +			mQ[VS] *= oomag; +		}  	}  	else  	{ diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 1e8b5517e4..ec52179a39 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -221,6 +221,7 @@ IF (NOT LINUX AND VIEWER)        # llhttpclientadapter.cpp        lltrustedmessageservice.cpp        lltemplatemessagedispatcher.cpp +      llregionpresenceverifier.cpp        )  #    set(TEST_DEBUG on)      set(test_libs @@ -241,3 +242,4 @@ IF (NOT LINUX AND VIEWER)      LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")  ENDIF (NOT LINUX AND VIEWER) + diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index 47d49076f4..c044b3d80d 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -100,7 +100,6 @@ public:  	// LEGACY  	boost::signals2::connection get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data); -  	// This method needs to be called from time to time to send out  	// requests.  	void processPending(); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp index b6988224ce..9d3c83f828 100644 --- a/indra/llmessage/llhttpclientadapter.cpp +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientadapter.cpp   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h index 7f76390d0c..a205a2f260 100644 --- a/indra/llmessage/llhttpclientadapter.h +++ b/indra/llmessage/llhttpclientadapter.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientadepter.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h index 42a8e5cd0a..085a59cf27 100644 --- a/indra/llmessage/llhttpclientinterface.h +++ b/indra/llmessage/llhttpclientinterface.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llhttpclientinterface.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index a00dbd1809..97134bd336 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -521,7 +521,7 @@ protected:  	 * seek orfor string assignment.  	 * @returns Returns true if a line was found.  	 */ -	bool readLine( +	bool readHeaderLine(  		const LLChannelDescriptors& channels,  		buffer_ptr_t buffer,  		U8* dest, @@ -592,7 +592,7 @@ LLHTTPResponder::~LLHTTPResponder()  	//lldebugs << "destroying LLHTTPResponder" << llendl;  } -bool LLHTTPResponder::readLine( +bool LLHTTPResponder::readHeaderLine(  	const LLChannelDescriptors& channels,  	buffer_ptr_t buffer,  	U8* dest, @@ -670,7 +670,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  #endif  		PUMP_DEBUG; -		if(readLine(channels, buffer, (U8*)buf, len)) +		if(readHeaderLine(channels, buffer, (U8*)buf, len))  		{  			bool read_next_line = false;  			bool parse_all = true; @@ -734,7 +734,13 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  					if(read_next_line)  					{  						len = HEADER_BUFFER_SIZE;	 -						readLine(channels, buffer, (U8*)buf, len); +						if (!readHeaderLine(channels, buffer, (U8*)buf, len)) +						{ +							// Failed to read the header line, probably too long. +							// readHeaderLine already marked the channel/buffer as bad. +							keep_parsing = false; +							break; +						}  					}  					if(0 == len)  					{ diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index d52ff6c7e8..ce206d8d7d 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -265,7 +265,7 @@ std::string LLMail::buildSMTPTransaction(  // static  bool LLMail::send(  	const std::string& header, -	const std::string& message, +	const std::string& raw_message,  	const char* from_address,  	const char* to_address)  { @@ -276,8 +276,20 @@ bool LLMail::send(  		return false;  	} -	// *FIX: this translation doesn't deal with a single period on a -	// line by itself. +	// remove any "." SMTP commands to prevent injection (DEV-35777) +	// we don't need to worry about "\r\n.\r\n" because of the  +	// "\n" --> "\n\n" conversion going into rfc2822_msg below +	std::string message = raw_message; +	std::string bad_string = "\n.\n"; +	std::string good_string = "\n..\n"; +	while (1) +	{ +		int index = message.find(bad_string); +		if (index == std::string::npos) break; +		message.replace(index, bad_string.size(), good_string); +	} + +	// convert all "\n" into "\r\n"  	std::ostringstream rfc2822_msg;  	for(U32 i = 0; i < message.size(); ++i)  	{ diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h index 119eb1d7f7..af6733fa05 100644 --- a/indra/llmessage/llmessagesenderinterface.h +++ b/indra/llmessage/llmessagesenderinterface.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llmessagesenderinterface.h   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp index 0527d5cb8d..4faad4468b 100644 --- a/indra/llmessage/llregionpresenceverifier.cpp +++ b/indra/llmessage/llregionpresenceverifier.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llregionpresenceverifier.cpp   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ @@ -36,11 +36,40 @@  #include "net.h"  #include "message.h" +namespace boost +{ +	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p) +	{ +		++p->mReferenceCount; +	} +	 +	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p) +	{ +		if(p && 0 == --p->mReferenceCount) +		{ +			delete p; +		} +	} +}; -LLRegionPresenceVerifier::RegionResponder::RegionResponder(ResponsePtr data) : mSharedData(data) +LLRegionPresenceVerifier::Response::~Response()  {  } +LLRegionPresenceVerifier::RegionResponder::RegionResponder(const std::string& +														   uri, +														   ResponsePtr data, +														   S32 retry_count) : +	mUri(uri), +	mSharedData(data), +	mRetryCount(retry_count) +{ +} + +//virtual +LLRegionPresenceVerifier::RegionResponder::~RegionResponder() +{ +}  void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content)  { @@ -53,26 +82,32 @@ void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content)  	std::stringstream uri;  	uri << "http://" << destination.getString() << "/state/basic/"; -	mSharedData->getHttpClient().get(uri.str(), new VerifiedDestinationResponder(mSharedData, content)); +	mSharedData->getHttpClient().get( +		uri.str(), +		new VerifiedDestinationResponder(mUri, mSharedData, content, mRetryCount));  } -void LLRegionPresenceVerifier::RegionResponder::completed( -	U32 status, -	const std::string& reason, -	const LLSD& content) +void LLRegionPresenceVerifier::RegionResponder::error(U32 status, +													 const std::string& reason)  { -	LLHTTPClient::Responder::completed(status, reason, content); -	 -	mSharedData->onCompletedRegionRequest(); +	// TODO: babbage: distinguish between region presence service and +	// region verification errors? +	mSharedData->onRegionVerificationFailed();  } - -LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(ResponsePtr data, const LLSD& content) : mSharedData(data), mContent(content) +LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(const std::string& uri, ResponsePtr data, const LLSD& content, +	S32 retry_count): +	mUri(uri), +	mSharedData(data), +	mContent(content), +	mRetryCount(retry_count)   {  } - - +//virtual +LLRegionPresenceVerifier::VerifiedDestinationResponder::~VerifiedDestinationResponder() +{ +}  void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD& content)  { @@ -87,13 +122,14 @@ void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD&  	{  		mSharedData->onRegionVerified(mContent);  	} -	else if (mSharedData->shouldRetry()) +	else if (mRetryCount > 0)  	{  		retry();  	}  	else  	{ -		llwarns << "Could not correctly look up region from region presence service. Region: " << mSharedData->getRegionUri() << llendl; +		llwarns << "Simulator verification failed. Region: " << mUri << llendl; +		mSharedData->onRegionVerificationFailed();  	}  } @@ -101,13 +137,21 @@ void LLRegionPresenceVerifier::VerifiedDestinationResponder::retry()  {  	LLSD headers;  	headers["Cache-Control"] = "no-cache, max-age=0"; -	llinfos << "Requesting region information, get uncached for region " << mSharedData->getRegionUri() << llendl; -	mSharedData->decrementRetries(); -	mSharedData->getHttpClient().get(mSharedData->getRegionUri(), new RegionResponder(mSharedData), headers); +	llinfos << "Requesting region information, get uncached for region " +			<< mUri << llendl; +	--mRetryCount; +	mSharedData->getHttpClient().get(mUri, new RegionResponder(mUri, mSharedData, mRetryCount), headers);  }  void LLRegionPresenceVerifier::VerifiedDestinationResponder::error(U32 status, const std::string& reason)  { -	retry(); +	if(mRetryCount > 0) +	{ +		retry(); +	} +	else +	{ +		llwarns << "Failed to contact simulator for verification. Region: " << mUri << llendl; +		mSharedData->onRegionVerificationFailed(); +	}  } - diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h index 54ad6226d6..f57a62a731 100644 --- a/indra/llmessage/llregionpresenceverifier.h +++ b/indra/llmessage/llregionpresenceverifier.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llregionpresenceverifier.cpp   * @brief    *   * $LicenseInfo:firstyear=2008&license=viewergpl$ @@ -37,7 +37,7 @@  #include "llhttpclient.h"  #include <string>  #include "llsd.h" -#include <boost/shared_ptr.hpp> +#include <boost/intrusive_ptr.hpp>  class LLHTTPClientInterface; @@ -47,49 +47,58 @@ public:  	class Response  	{  	public: -		virtual ~Response() {} +		virtual ~Response() = 0;  		virtual bool checkValidity(const LLSD& content) const = 0;  		virtual void onRegionVerified(const LLSD& region_details) = 0; - -		virtual void decrementRetries() = 0; +		virtual void onRegionVerificationFailed() = 0;  		virtual LLHTTPClientInterface& getHttpClient() = 0; -		virtual std::string getRegionUri() const = 0; -		virtual bool shouldRetry() const = 0; -		virtual void onCompletedRegionRequest() {} +	public: /* but not really -- don't touch this */ +		U32 mReferenceCount;		  	}; -	typedef boost::shared_ptr<Response> ResponsePtr; +	typedef boost::intrusive_ptr<Response> ResponsePtr;  	class RegionResponder : public LLHTTPClient::Responder  	{  	public: -		RegionResponder(ResponsePtr data); +		RegionResponder(const std::string& uri, ResponsePtr data, +						S32 retry_count); +		virtual ~RegionResponder();   		virtual void result(const LLSD& content); -		virtual void completed( -			U32 status, -			const std::string& reason, -			const LLSD& content); +		virtual void error(U32 status, const std::string& reason);  	private:  		ResponsePtr mSharedData; +		std::string mUri; +		S32 mRetryCount;  	};  	class VerifiedDestinationResponder : public LLHTTPClient::Responder  	{  	public: -		VerifiedDestinationResponder(ResponsePtr data, const LLSD& content); +		VerifiedDestinationResponder(const std::string& uri, ResponsePtr data, +									 const LLSD& content, S32 retry_count); +		virtual ~VerifiedDestinationResponder();  		virtual void result(const LLSD& content);  		virtual void error(U32 status, const std::string& reason); +		  	private:  		void retry();  		ResponsePtr mSharedData;  		LLSD mContent; +		std::string mUri; +		S32 mRetryCount;  	};  }; +namespace boost +{ +	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p); +	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p); +};  #endif //LL_LLREGIONPRESENCEVERIFIER_H diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp index 32cbb15cb3..d6b2f45d04 100644 --- a/indra/llmessage/llstoredmessage.cpp +++ b/indra/llmessage/llstoredmessage.cpp @@ -1,5 +1,5 @@  /**  - * @file  + * @file llstoredmessage.cpp   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h index 5069c2cb2e..359e4c5aea 100644 --- a/indra/llmessage/llstoredmessage.h +++ b/indra/llmessage/llstoredmessage.h @@ -1,5 +1,5 @@  /**  - * @file  + * @file llstoredmessage.h   * @brief    *   * $LicenseInfo:firstyear=2009&license=viewergpl$ diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 70279a3c62..0872efba50 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -265,6 +265,31 @@ BOOL LLThrottleGroup::setNominalBPS(F32* throttle_vec)  	return changed;  } +// Return bits available in the channel +S32		LLThrottleGroup::getAvailable(S32 throttle_cat) +{ +	S32 retval = 0; + +	F32 category_bps = mCurrentBPS[throttle_cat]; +	F32 lookahead_bits = category_bps * THROTTLE_LOOKAHEAD_TIME; + +	// use a temporary bits_available +	// since we don't want to change mBitsAvailable every time +	F32 elapsed_time = (F32)(LLMessageSystem::getMessageTimeSeconds() - mLastSendTime[throttle_cat]); +	F32 bits_available = mBitsAvailable[throttle_cat] + (category_bps * elapsed_time); + +	if (bits_available >= lookahead_bits) +	{ +		retval = (S32) gThrottleMaximumBPS[throttle_cat]; +	} +	else  +	{ +		retval = (S32) bits_available; +	} +	 +	return retval; +} +  BOOL LLThrottleGroup::checkOverflow(S32 throttle_cat, F32 bits)  { diff --git a/indra/llmessage/llthrottle.h b/indra/llmessage/llthrottle.h index 7d1679beb2..47a7c653b2 100644 --- a/indra/llmessage/llthrottle.h +++ b/indra/llmessage/llthrottle.h @@ -84,6 +84,8 @@ public:  	BOOL	dynamicAdjust();		// Shift bandwidth from idle channels to busy channels, TRUE if adjustment occurred  	BOOL	setNominalBPS(F32* throttle_vec);				// TRUE if any value was different, resets adjustment system if was different +	S32		getAvailable(S32 throttle_cat);					// Return bits available in the channel +  	void packThrottle(LLDataPacker &dp) const;  	void unpackThrottle(LLDataPacker &dp);  public: diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 3ab8057abb..81b7761ed5 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -51,6 +51,7 @@ static const U32 HTTP_STATUS_PIPE_ERROR = 499;   * String constants   */  const std::string CONTEXT_DEST_URI_SD_LABEL("dest_uri"); +const std::string CONTEXT_TRANSFERED_BYTES("transfered_bytes");  static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); @@ -247,7 +248,29 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	PUMP_DEBUG;  	LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);  	//llinfos << "LLURLRequest::process_impl()" << llendl; -	if(!buffer) return STATUS_ERROR; +	if (!buffer) return STATUS_ERROR; +	 +	// we're still waiting or prcessing, check how many +	// bytes we have accumulated. +	const S32 MIN_ACCUMULATION = 100000; +	if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION)) +	{ +		 // This is a pretty sloppy calculation, but this +		 // tries to make the gross assumption that if data +		 // is coming in at 56kb/s, then this transfer will +		 // probably succeed. So, if we're accumlated +		 // 100,000 bytes (MIN_ACCUMULATION) then let's +		 // give this client another 2s to complete. +		 const F32 TIMEOUT_ADJUSTMENT = 2.0f; +		 mDetail->mByteAccumulator = 0; +		 pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT); +		 lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl; +		 if (mState == STATE_INITIALIZED) +		 { +			  llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl; +		 } +	} +  	switch(mState)  	{  	case STATE_INITIALIZED: @@ -286,27 +309,14 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  			bool newmsg = mDetail->mCurlRequest->getResult(&result);  			if(!newmsg)  			{ -				// we're still waiting or prcessing, check how many -				// bytes we have accumulated. -				const S32 MIN_ACCUMULATION = 100000; -				if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION)) -				{ -					// This is a pretty sloppy calculation, but this -					// tries to make the gross assumption that if data -					// is coming in at 56kb/s, then this transfer will -					// probably succeed. So, if we're accumlated -					// 100,000 bytes (MIN_ACCUMULATION) then let's -					// give this client another 2s to complete. -					const F32 TIMEOUT_ADJUSTMENT = 2.0f; -					mDetail->mByteAccumulator = 0; -					pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT); -				} -  				// keep processing  				break;  			}  			mState = STATE_HAVE_RESPONSE; +			context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +			context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +			lldebugs << this << "Setting context to " << context << llendl;  			switch(result)  			{  				case CURLE_OK: @@ -353,10 +363,16 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  		// we already stuffed everything into channel in in the curl  		// callback, so we are done.  		eos = true; +		context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +		context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +		lldebugs << this << "Setting context to " << context << llendl;  		return STATUS_DONE;  	default:  		PUMP_DEBUG; +		context[CONTEXT_REQUEST][CONTEXT_TRANSFERED_BYTES] = mRequestTransferedBytes; +		context[CONTEXT_RESPONSE][CONTEXT_TRANSFERED_BYTES] = mResponseTransferedBytes; +		lldebugs << this << "Setting context to " << context << llendl;  		return STATUS_ERROR;  	}  } @@ -369,6 +385,8 @@ void LLURLRequest::initialize()  	mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);  	mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);  	mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this); +	mRequestTransferedBytes = 0; +	mResponseTransferedBytes = 0;  }  bool LLURLRequest::configure() @@ -471,6 +489,7 @@ size_t LLURLRequest::downCallback(  		req->mDetail->mChannels.out(),  		(U8*)data,  		bytes); +	req->mResponseTransferedBytes += bytes;  	req->mDetail->mByteAccumulator += bytes;  	return bytes;  } @@ -494,6 +513,7 @@ size_t LLURLRequest::upCallback(  		req->mDetail->mLastRead,  		(U8*)data,  		bytes); +	req->mRequestTransferedBytes += bytes;  	return bytes;  } diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 86ef71f085..cb3c466440 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -45,6 +45,12 @@  #include "llchainio.h"  #include "llerror.h" + +extern const std::string CONTEXT_REQUEST; +extern const std::string CONTEXT_DEST_URI_SD_LABEL; +extern const std::string CONTEXT_RESPONSE; +extern const std::string CONTEXT_TRANSFERED_BYTES; +  class LLURLRequestDetail;  class LLURLRequestComplete; @@ -208,6 +214,8 @@ protected:  	ERequestAction mAction;  	LLURLRequestDetail* mDetail;  	LLIOPipe::ptr_t mCompletionCallback; +	 S32 mRequestTransferedBytes; +	 S32 mResponseTransferedBytes;  private:  	/**  diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 08c9192c9f..209bdb2249 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -760,30 +760,36 @@ static bool remove_prefix(std::string& filename, const std::string& prefix)  static bool verify_cache_filename(const std::string& filename)  {  	//NOTE: This routine is only used to check file names that our own -	// code places in the cache directory.  As such, it can be limited -	// to this very restrictive file name pattern.  It does not need to -	// handle other characters. - +	// code places in the cache directory.	As such, it can be limited +	// to this very restrictive file name pattern.	It does not need to +	// handle other characters. The only known uses of this are (with examples): +	//	sim to sim object pass:			fc0b72d8-9456-63d9-a802-a557ef847313.tmp +	//	sim to viewer mute list:		mute_b78eacd0-1244-448e-93ca-28ede242f647.tmp +	//	sim to viewer task inventory:	inventory_d8ab59d2-baf0-0e79-c4c2-a3f99b9fcf45.tmp +	 +	//IMPORTANT: Do not broaden the filenames accepted by this routine +	// without careful analysis. Anything allowed by this function can +	// be downloaded by the viewer. +	  	size_t len = filename.size(); -	//const boost::regex expr("[a-zA-Z0-9][-_.a-zA-Z0-9]<0,49>"); -	if (len < 1 || len > 50) -	{ +	//const boost::regex expr("[0-9a-zA-Z_-]<1,46>\.tmp"); +	if (len < 5 || len > 50) +	{	  		return false;  	} -	for(unsigned i=0; i<len; ++i) -	{ +	for(size_t i=0; i<(len-4); ++i) +	{	  		char c = filename[i]; -		bool ok = isalnum(c); -		if (!ok && i > 0) -		{ -			ok = '_'==c || '-'==c || '.'==c; -		} +		bool ok = isalnum(c) || '_'==c || '-'==c;  		if (!ok)  		{  			return false;  		}  	} -	return true; +	return filename[len-4] == '.' +		&& filename[len-3] == 't' +		&& filename[len-2] == 'm' +		&& filename[len-1] == 'p';  }  void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) diff --git a/indra/llmessage/tests/llmockhttpclient.h b/indra/llmessage/tests/llmockhttpclient.h new file mode 100644 index 0000000000..2f55e97fcc --- /dev/null +++ b/indra/llmessage/tests/llmockhttpclient.h @@ -0,0 +1,61 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLMOCKHTTPCLIENT_H +#define LL_LLMOCKHTTPCLIENT_H + +#include "linden_common.h" +#include "llhttpclientinterface.h" + +#include <gmock/gmock.h> + +class LLMockHTTPClient : public LLHTTPClientInterface +{ +public: +  MOCK_METHOD2(get, void(const std::string& url, LLCurl::ResponderPtr responder)); +  MOCK_METHOD3(get, void(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)); +  MOCK_METHOD3(put, void(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)); +}; + +// A helper to match responder types +template<typename T> +struct ResponderType +{ +	bool operator()(LLCurl::ResponderPtr ptr) const +	{ +		T* p = dynamic_cast<T*>(ptr.get()); +		return p != NULL; +	} +}; + +inline bool operator==(const LLSD& l, const LLSD& r) +{ +	std::ostringstream ls, rs; +	ls << l; +	rs << r; +	return ls.str() == rs.str(); + +} + + +#endif //LL_LLMOCKHTTPCLIENT_H + diff --git a/indra/llmessage/tests/llregionpresenceverifier_test.cpp b/indra/llmessage/tests/llregionpresenceverifier_test.cpp new file mode 100644 index 0000000000..b7602ef15c --- /dev/null +++ b/indra/llmessage/tests/llregionpresenceverifier_test.cpp @@ -0,0 +1,111 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "../test/lltut.h" +#include "llregionpresenceverifier.h" +#include "llcurl_stub.cpp" +#include "llhost.cpp" +#include "net.cpp" +#include "lltesthttpclientadapter.cpp" + +class LLTestResponse : public LLRegionPresenceVerifier::Response +{ +public: + +	virtual bool checkValidity(const LLSD& content) const +	{ +		return true; +	} + +	virtual void onRegionVerified(const LLSD& region_details) +	{ +	} + +	virtual void onRegionVerificationFailed() +	{ +	} +	 +	virtual LLHTTPClientInterface& getHttpClient() +	{ +		return mHttpInterface; +	} + +	LLTestHTTPClientAdapter mHttpInterface; +}; + +namespace tut +{ +	struct LLRegionPresenceVerifierData +	{ +		LLRegionPresenceVerifierData() : +			mResponse(new LLTestResponse()), +			mResponder("", LLRegionPresenceVerifier::ResponsePtr(mResponse), +					   LLSD(), 3) +		{ +		} +		 +		LLTestResponse* mResponse; +		LLRegionPresenceVerifier::VerifiedDestinationResponder mResponder; +	}; + +	typedef test_group<LLRegionPresenceVerifierData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLRegionPresenceVerifier test"); +} + +namespace tut +{ +	// Test that VerifiedDestinationResponder does retry +    // on error when shouldRetry returns true. +	template<> template<> +	void object::test<1>() +	{ +		mResponder.error(500, "Internal server error"); +		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 1); +	} + +	// Test that VerifiedDestinationResponder only retries +	// on error until shouldRetry returns false. +	template<> template<> +	void object::test<2>() +	{ +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		mResponder.error(500, "Internal server error"); +		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 3); +	} +} + diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 33807e7545..dcfb5cfae6 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -746,16 +746,201 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai  	U32 old_face_mask = mVolumep->mFaceMask; +	S32 face_bit = 0; +	S32 cur_mask = 0; + +	// Grab copies of the old faces from the original shape, ordered by type. +	// We will use these to figure out what old texture info gets mapped to new +	// faces in the new shape. +	std::vector<LLProfile::Face> old_faces;  +	for (S32 face = 0; face < mVolumep->getNumFaces(); face++) +	{ +		old_faces.push_back(mVolumep->getProfile().mFaces[face]); +	} + +	// Copy the old texture info off to the side, but not in the order in which +	// they live in the mTextureList, rather in order of ther "face id" which +	// is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. +	// +	// Hence, some elements of old_tes::mEntryList will be invalid.  It is +	// initialized to a size of 9 (max number of possible faces on a volume?) +	// and only the ones with valid types are filled in. +	LLPrimTextureList old_tes; +	old_tes.setSize(9); +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		cur_mask = 0x1 << face_bit; +		if (old_face_mask & cur_mask) +		{ +			S32 te_index = face_index_from_id(cur_mask, old_faces); +			old_tes.copyTexture(face_bit, *(getTE(te_index))); +			//llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; +		} +	} + +  	// build the new object  	sVolumeManager->unrefVolume(mVolumep);  	mVolumep = volumep;  	U32 new_face_mask = mVolumep->mFaceMask; -	if (old_face_mask != new_face_mask)  +	S32 i; + +	if (old_face_mask == new_face_mask)  +	{ +		// nothing to do +		return TRUE; +	} + +	if (mVolumep->getNumFaces() == 0 && new_face_mask != 0)  	{ +		llwarns << "Object with 0 faces found...INCORRECT!" << llendl;  		setNumTEs(mVolumep->getNumFaces()); +		return TRUE; +	} + +	// initialize face_mapping +	S32 face_mapping[9]; +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		face_mapping[face_bit] = face_bit; +	} + +	// The new shape may have more faces than the original, but we can't just +	// add them to the end -- the ordering matters and it may be that we must +	// insert the new faces in the middle of the list.  When we add a face it +	// will pick up the texture/color info of one of the old faces an so we +	// now figure out which old face info gets mapped to each new face, and  +	// store in the face_mapping lookup table. +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		cur_mask = 0x1 << face_bit; +		if (!(new_face_mask & cur_mask)) +		{ +			// Face doesn't exist in new map. +			face_mapping[face_bit] = -1; +			continue; +		} +		else if (old_face_mask & cur_mask) +		{ +			// Face exists in new and old map. +			face_mapping[face_bit] = face_bit; +			continue; +		} + +		// OK, how we've got a mismatch, where we have to fill a new face with one from +		// the old face. +		if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) +		{ +			// It's a top/bottom/hollow interior face. +			if (old_face_mask & LL_FACE_PATH_END) +			{ +				face_mapping[face_bit] = 1; +				continue; +			} +			else +			{ +				S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; +				for (i = 0; i < 4; i++) +				{ +					if (old_face_mask & cur_outer_mask) +					{ +						face_mapping[face_bit] = 5 + i; +						break; +					} +					cur_outer_mask <<= 1; +				} +				if (i == 4) +				{ +					llwarns << "No path end or outer face in volume!" << llendl; +				} +				continue; +			} +		} + +		if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) +		{ +			// A cut slice.  Use the hollow interior if we have it. +			if (old_face_mask & LL_FACE_INNER_SIDE) +			{ +				face_mapping[face_bit] = 2; +				continue; +			} + +			// No interior, use the bottom face. +			// Could figure out which of the outer faces was nearest, but that would be harder. +			if (old_face_mask & LL_FACE_PATH_END) +			{ +				face_mapping[face_bit] = 1; +				continue; +			} +			else +			{ +				S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; +				for (i = 0; i < 4; i++) +				{ +					if (old_face_mask & cur_outer_mask) +					{ +						face_mapping[face_bit] = 5 + i; +						break; +					} +					cur_outer_mask <<= 1; +				} +				if (i == 4) +				{ +					llwarns << "No path end or outer face in volume!" << llendl; +				} +				continue; +			} +		} + +		// OK, the face that's missing is an outer face... +		// Pull from the nearest adjacent outer face (there's always guaranteed to be one... +		S32 cur_outer = face_bit - 5; +		S32 min_dist = 5; +		S32 min_outer_bit = -1; +		S32 i; +		for (i = 0; i < 4; i++) +		{ +			if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) +			{ +				S32 dist = abs(i - cur_outer); +				if (dist < min_dist) +				{ +					min_dist = dist; +					min_outer_bit = i + 5; +				} +			} +		} +		if (-1 == min_outer_bit) +		{ +			llinfos << (LLVolume *)mVolumep << llendl; +			llwarns << "Bad!  No outer faces, impossible!" << llendl; +		} +		face_mapping[face_bit] = min_outer_bit;  	} +	 + +	setNumTEs(mVolumep->getNumFaces()); +	for (face_bit = 0; face_bit < 9; face_bit++) +	{ +		// For each possible face type on the new shape we check to see if that +		// face exists and if it does we create a texture entry that is a copy +		// of one of the originals.  Since the originals might not have a +		// matching face, we use the face_mapping lookup table to figure out +		// which face information to copy. +		cur_mask = 0x1 << face_bit; +		if (new_face_mask & cur_mask) +		{ +			if (-1 == face_mapping[face_bit]) +			{ +				llwarns << "No mapping from old face to new face!" << llendl; +			} +			S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); +			setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); +		} +	}  	return TRUE;  } @@ -1314,6 +1499,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)  		return (size == 16);  	case PARAMS_SCULPT:  		return (size == 17); +	case PARAMS_LIGHT_IMAGE: +		return (size == 28);  	}  	return FALSE; @@ -1646,3 +1833,79 @@ bool LLSculptParams::fromLLSD(LLSD& sd)  	return false;  } +//============================================================================ + +LLLightImageParams::LLLightImageParams() +{ +	mType = PARAMS_LIGHT_IMAGE; +	mParams.setVec(F_PI*0.5f, 0.f, 0.f); +} + +BOOL LLLightImageParams::pack(LLDataPacker &dp) const +{ +	dp.packUUID(mLightTexture, "texture"); +	dp.packVector3(mParams, "params"); + +	return TRUE; +} + +BOOL LLLightImageParams::unpack(LLDataPacker &dp) +{ +	dp.unpackUUID(mLightTexture, "texture"); +	dp.unpackVector3(mParams, "params"); +	 +	return TRUE; +} + +bool LLLightImageParams::operator==(const LLNetworkData& data) const +{ +	if (data.mType != PARAMS_LIGHT_IMAGE) +	{ +		return false; +	} +	 +	const LLLightImageParams *param = (const LLLightImageParams*)&data; +	if ( (param->mLightTexture != mLightTexture) ) +	{ +		return false; +	} + +	if ( (param->mParams != mParams ) ) +	{ +		return false; +	} +	 +	return true; +} + +void LLLightImageParams::copy(const LLNetworkData& data) +{ +	const LLLightImageParams *param = (LLLightImageParams*)&data; +	mLightTexture = param->mLightTexture; +	mParams = param->mParams; +} + + + +LLSD LLLightImageParams::asLLSD() const +{ +	LLSD sd; +	 +	sd["texture"] = mLightTexture; +	sd["params"] = mParams.getValue(); +		 +	return sd; +} + +bool LLLightImageParams::fromLLSD(LLSD& sd) +{ +	if (sd.has("texture")) +	{ +		setLightTexture( sd["texture"] ); +		setParams( LLVector3( sd["params"] ) ); +		return true; +	}  +	 +	return false; +} + diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index b3a337ce5d..53095cc925 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -107,7 +107,8 @@ public:  	{  		PARAMS_FLEXIBLE = 0x10,  		PARAMS_LIGHT    = 0x20, -		PARAMS_SCULPT   = 0x30 +		PARAMS_SCULPT   = 0x30, +		PARAMS_LIGHT_IMAGE = 0x40,  	};  public: @@ -267,6 +268,28 @@ public:  	U8 getSculptType()                      { return mSculptType; }  }; +class LLLightImageParams : public LLNetworkData +{ +protected: +	LLUUID mLightTexture; +	LLVector3 mParams; +	 +public: +	LLLightImageParams(); +	/*virtual*/ BOOL pack(LLDataPacker &dp) const; +	/*virtual*/ BOOL unpack(LLDataPacker &dp); +	/*virtual*/ bool operator==(const LLNetworkData& data) const; +	/*virtual*/ void copy(const LLNetworkData& data); +	LLSD asLLSD() const; +	operator LLSD() const { return asLLSD(); } +	bool fromLLSD(LLSD& sd); + +	void setLightTexture(const LLUUID& id) { mLightTexture = id; } +	LLUUID getLightTexture() const         { return mLightTexture; } +	void setParams(const LLVector3& params) { mParams = params; } +	LLVector3 getParams() const			   { return mParams; } +	 +};  class LLPrimitive : public LLXform diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp index d03150fc78..1c7de95975 100644 --- a/indra/llprimitive/llprimtexturelist.cpp +++ b/indra/llprimitive/llprimtexturelist.cpp @@ -135,13 +135,12 @@ S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te)  {  	if (S32(index) >= mEntryList.size())  	{ -		// TODO -- assert here  		S32 current_size = mEntryList.size(); -		llerrs << "index = " << S32(index) << "  current_size = " << current_size << llendl; +		llwarns << "ignore copy of index = " << S32(index) << " into texture entry list of size = " << current_size << llendl;  		return TEM_CHANGE_NONE;  	} -	// we're changing an existing entry +		// we're changing an existing entry  	llassert(mEntryList[index]);  	delete (mEntryList[index]);  	if  (&te) @@ -387,8 +386,18 @@ void LLPrimTextureList::setSize(S32 new_size)  		mEntryList.resize(new_size);  		for (S32 index = current_size; index < new_size; ++index)  		{ -			LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); -			mEntryList[index] = new_entry; +			if (current_size > 0 +				&& mEntryList[current_size - 1]) +			{ +				// copy the last valid entry for the new one +				mEntryList[index] = mEntryList[current_size - 1]->newCopy(); +			} +			else +			{ +				// no valid enries to copy, so we new one up +				LLTextureEntry* new_entry = LLPrimTextureList::newTextureEntry(); +				mEntryList[index] = new_entry; +			}  		}  	}  	else if (new_size < current_size) diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp index 93ac120302..315baa001d 100755 --- a/indra/llvfs/llpidlock.cpp +++ b/indra/llvfs/llpidlock.cpp @@ -62,7 +62,7 @@ class LLPidLockFile  			mSaving(FALSE), mWaiting(FALSE),   			mClean(TRUE), mPID(getpid())  		{ -			mLockName = gDirUtilp->getTempDir() + "/savelock"; +			mLockName = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + "savelock";  		}  		bool requestLock(LLNameTable<void *> *name_table, bool autosave,  						bool force_immediate=FALSE, F32 timeout=300.0); diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h index ba2c46bef2..a54ebd5831 100644 --- a/indra/lscript/lscript_byteformat.h +++ b/indra/lscript/lscript_byteformat.h @@ -556,7 +556,7 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =  // http_request string constants  extern const char* URL_REQUEST_GRANTED;  extern const char* URL_REQUEST_DENIED; -extern const U64 LSL_HTTP_REQUEST_TIMEOUT; +extern const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC;  #endif diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp index 98146d6f2b..3b8bbbe805 100644 --- a/indra/lscript/lscript_compile/lscript_tree.cpp +++ b/indra/lscript/lscript_compile/lscript_tree.cpp @@ -631,9 +631,7 @@ static void print_cil_cast(LLFILE* fp, LSCRIPTType srcType, LSCRIPTType targetTy  		switch(targetType)  		{  		case LST_INTEGER: -			//fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\n"); -			fprintf(fp, "conv.i4\n"); // TODO replace this line with the above -			// we the entire grid is > 1.25.1 +			fprintf(fp, "call int32 [LslLibrary]LindenLab.SecondLife.LslRunTime::ToInteger(float32)\n");  			break;  		case LST_STRING:  			fprintf(fp, "call string [LslLibrary]LindenLab.SecondLife.LslRunTime::ToString(float32)\n"); @@ -8375,10 +8373,18 @@ void LLScriptStateChange::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTComp  			chunk->addInteger(mIdentifier->mScopeEntry->mCount);  		}  		break; +	case LSCP_TYPE: +		mReturnType = basetype; +		break;  	case LSCP_EMIT_CIL_ASSEMBLY:  		fprintf(fp, "ldarg.0\n");  		fprintf(fp, "ldstr \"%s\"\n", mIdentifier->mName);  		fprintf(fp, "call instance void class [LslUserScript]LindenLab.SecondLife.LslUserScript::ChangeState(string)\n"); +		// We are doing a state change. In the LSL interpreter, this is basically a longjmp. We emulate it +		// here using a call to the ChangeState followed by a short cut return of the current method. To +		// maintain type safety we need to push an arbitrary variable of the current method's return type +		// onto the stack before returning. This will be ignored and discarded. +		print_cil_init_variable(fp, mReturnType);  		fprintf(fp, "ret\n");  		break;  	default: diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h index 12c16908af..a667e1eb5b 100644 --- a/indra/lscript/lscript_compile/lscript_tree.h +++ b/indra/lscript/lscript_compile/lscript_tree.h @@ -1888,6 +1888,7 @@ public:  	S32 getSize();  	LLScriptIdentifier *mIdentifier; +	LSCRIPTType mReturnType;  };  class LLScriptJump : public LLScriptStatement diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h index 245fc320d1..96855abea0 100644 --- a/indra/lscript/lscript_execute.h +++ b/indra/lscript/lscript_execute.h @@ -371,8 +371,7 @@ class LLScriptExecute  {  public:  	LLScriptExecute(); -	virtual ~LLScriptExecute() {;} - +	virtual ~LLScriptExecute()  = 0;  	virtual S32 getVersion() const = 0;  	virtual void deleteAllEvents() = 0;  	virtual void addEvent(LLScriptDataCollection* event) = 0; diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index 2fd81210c0..e849fa9a6e 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -41,6 +41,8 @@  #include "lscript_library.h"  #include "lscript_heapruntime.h"  #include "lscript_alloc.h" +#include "llstat.h" +  // Static  const	S32	DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4; @@ -72,7 +74,7 @@ const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";  const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";  // HTTP Requests to LSL scripts will time out after 25 seconds. -const U64 LSL_HTTP_REQUEST_TIMEOUT = 25 * USEC_PER_SEC;  +const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC = 25 * USEC_PER_SEC;   LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)  { @@ -110,6 +112,7 @@ LLScriptExecuteLSL2::LLScriptExecuteLSL2(const U8* bytecode, U32 bytecode_size)  	init();  } +LLScriptExecute::~LLScriptExecute() {}  LLScriptExecuteLSL2::~LLScriptExecuteLSL2()  {  	delete[] mBuffer; @@ -4234,19 +4237,16 @@ S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer)  	return 4;  } -BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) + +// Shared code for run_calllib() and run_calllib_two_byte() +BOOL run_calllib_common(U8 *buffer, S32 &offset, const LLUUID &id, U16 arg)  { -	if (b_print) -		printf("[0x%X]\tCALLLIB ", offset); -	offset++; -	U8 arg = safe_instruction_bytestream2byte(buffer, offset); -	if (arg >= (U8)gScriptLibrary.mFunctions.size()) +	if (arg >= gScriptLibrary.mFunctions.size())  	{  		set_fault(buffer, LSRF_BOUND_CHECK_ERROR);  		return FALSE;  	} -	if (b_print) -		printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName); +	LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg];  	// pull out the arguments and the return values  	LLScriptLibData	*arguments = NULL; @@ -4254,14 +4254,14 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  	S32 i, number; -	if (gScriptLibrary.mFunctions[arg].mReturnType) +	if (function.mReturnType)  	{  		returnvalue = new LLScriptLibData;  	} -	if (gScriptLibrary.mFunctions[arg].mArgs) +	if (function.mArgs)  	{ -		number = (S32)strlen(gScriptLibrary.mFunctions[arg].mArgs);		/*Flawfinder: ignore*/ +		number = (S32)strlen(function.mArgs);		//Flawfinder: ignore  		arguments = new LLScriptLibData[number];  	}  	else @@ -4271,23 +4271,18 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  	for (i = number - 1; i >= 0; i--)  	{ -		lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg].mArgs[i]); +		lscript_pop_variable(&arguments[i], buffer, function.mArgs[i]);  	} -	if (b_print) -	{ -		printf("See LSLTipText_%s in strings.xml for usage\n", gScriptLibrary.mFunctions[arg].mName); -	} +	// Actually execute the function call +	function.mExecFunc(returnvalue, arguments, id); -	{ -		gScriptLibrary.mFunctions[arg].mExecFunc(returnvalue, arguments, id); -	} -	add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg].mEnergyUse); -	add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg].mSleepTime); +	add_register_fp(buffer, LREG_ESR, -(function.mEnergyUse)); +	add_register_fp(buffer, LREG_SLR, function.mSleepTime);  	if (returnvalue)  	{ -		returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg].mReturnType); +		returnvalue->mType = char2type(*function.mReturnType);  		lscript_push_return_variable(returnvalue, buffer);  	} @@ -4304,71 +4299,32 @@ BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  } -BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) +BOOL run_calllib(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)  { -	if (b_print) -		printf("[0x%X]\tCALLLIB ", offset);  	offset++; -	U16 arg = safe_instruction_bytestream2u16(buffer, offset); -	if (arg >= (U16)gScriptLibrary.mFunctions.size()) +	U16 arg = (U16) safe_instruction_bytestream2byte(buffer, offset); +	if (b_print && +		arg < gScriptLibrary.mFunctions.size())  	{ -		set_fault(buffer, LSRF_BOUND_CHECK_ERROR); -		return FALSE; -	} -	if (b_print) -		printf("%d (%s)\n", (U32)arg, gScriptLibrary.mFunctions[arg].mName); - -	// pull out the arguments and the return values -	LLScriptLibData	*arguments = NULL; -	LLScriptLibData	*returnvalue = NULL; - -	S32 i, number; - -	if (gScriptLibrary.mFunctions[arg].mReturnType) -	{ -		returnvalue = new LLScriptLibData; -	} - -	if (gScriptLibrary.mFunctions[arg].mArgs) -	{ -		number = (S32)strlen(gScriptLibrary.mFunctions[arg].mArgs);		/*Flawfinder: ignore*/ -		arguments = new LLScriptLibData[number]; -	} -	else -	{ -		number = 0; -	} - -	for (i = number - 1; i >= 0; i--) -	{ -		lscript_pop_variable(&arguments[i], buffer, gScriptLibrary.mFunctions[arg].mArgs[i]); -	} - -	if (b_print) -	{ -		printf("See LSLTipText_%s in strings.xml for usage\n", gScriptLibrary.mFunctions[arg].mName); -	} - -	{ -		gScriptLibrary.mFunctions[arg].mExecFunc(returnvalue, arguments, id); +		printf("[0x%X]\tCALLLIB ", offset); +		LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg]; +		printf("%d (%s)\n", (U32)arg, function.mName); +		//printf("%s\n", function.mDesc);  	} -	add_register_fp(buffer, LREG_ESR, -gScriptLibrary.mFunctions[arg].mEnergyUse); -	add_register_fp(buffer, LREG_SLR, gScriptLibrary.mFunctions[arg].mSleepTime); +	return run_calllib_common(buffer, offset, id, arg); +} -	if (returnvalue) +BOOL run_calllib_two_byte(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) +{ +	offset++; +	U16 arg = safe_instruction_bytestream2u16(buffer, offset); +	if (b_print && +		arg < gScriptLibrary.mFunctions.size())  	{ -		returnvalue->mType = char2type(*gScriptLibrary.mFunctions[arg].mReturnType); -		lscript_push_return_variable(returnvalue, buffer); +		printf("[0x%X]\tCALLLIB ", (offset-1)); +		LLScriptLibraryFunction const & function = gScriptLibrary.mFunctions[arg]; +		printf("%d (%s)\n", (U32)arg, function.mName); +		//printf("%s\n", function.mDesc);  	} - -	delete [] arguments; -	delete returnvalue; - -	// reset the BP after calling the library files -	S32 bp = lscript_pop_int(buffer); -	set_bp(buffer, bp); - -	// pop off the spot for the instruction pointer -	lscript_poparg(buffer, 4); -	return FALSE; +	return run_calllib_common(buffer, offset, id, arg);  } diff --git a/indra/newview/character/avatar_eye.llm b/indra/newview/character/avatar_eye.llmBinary files differ new file mode 100644 index 0000000000..8c6e74e1de --- /dev/null +++ b/indra/newview/character/avatar_eye.llm diff --git a/indra/newview/character/avatar_eye_1.llm b/indra/newview/character/avatar_eye_1.llmBinary files differ new file mode 100644 index 0000000000..7a3b0d6f28 --- /dev/null +++ b/indra/newview/character/avatar_eye_1.llm diff --git a/indra/newview/character/avatar_eyelashes.llm b/indra/newview/character/avatar_eyelashes.llmBinary files differ new file mode 100644 index 0000000000..99995b5758 --- /dev/null +++ b/indra/newview/character/avatar_eyelashes.llm diff --git a/indra/newview/character/avatar_hair.llm b/indra/newview/character/avatar_hair.llmBinary files differ new file mode 100644 index 0000000000..df99de8db7 --- /dev/null +++ b/indra/newview/character/avatar_hair.llm diff --git a/indra/newview/character/avatar_hair_1.llm b/indra/newview/character/avatar_hair_1.llmBinary files differ new file mode 100644 index 0000000000..6de31fdc23 --- /dev/null +++ b/indra/newview/character/avatar_hair_1.llm diff --git a/indra/newview/character/avatar_hair_2.llm b/indra/newview/character/avatar_hair_2.llmBinary files differ new file mode 100644 index 0000000000..47d02ba9ce --- /dev/null +++ b/indra/newview/character/avatar_hair_2.llm diff --git a/indra/newview/character/avatar_hair_3.llm b/indra/newview/character/avatar_hair_3.llmBinary files differ new file mode 100644 index 0000000000..107f9e2a53 --- /dev/null +++ b/indra/newview/character/avatar_hair_3.llm diff --git a/indra/newview/character/avatar_hair_4.llm b/indra/newview/character/avatar_hair_4.llmBinary files differ new file mode 100644 index 0000000000..1b9a12a0ca --- /dev/null +++ b/indra/newview/character/avatar_hair_4.llm diff --git a/indra/newview/character/avatar_hair_5.llm b/indra/newview/character/avatar_hair_5.llmBinary files differ new file mode 100644 index 0000000000..1b9a12a0ca --- /dev/null +++ b/indra/newview/character/avatar_hair_5.llm diff --git a/indra/newview/character/avatar_head.llm b/indra/newview/character/avatar_head.llmBinary files differ new file mode 100644 index 0000000000..8d8b5e0442 --- /dev/null +++ b/indra/newview/character/avatar_head.llm diff --git a/indra/newview/character/avatar_head_1.llm b/indra/newview/character/avatar_head_1.llmBinary files differ new file mode 100644 index 0000000000..26291e6584 --- /dev/null +++ b/indra/newview/character/avatar_head_1.llm diff --git a/indra/newview/character/avatar_head_2.llm b/indra/newview/character/avatar_head_2.llmBinary files differ new file mode 100644 index 0000000000..c2b808b1a6 --- /dev/null +++ b/indra/newview/character/avatar_head_2.llm diff --git a/indra/newview/character/avatar_head_3.llm b/indra/newview/character/avatar_head_3.llmBinary files differ new file mode 100644 index 0000000000..a0676b1f1c --- /dev/null +++ b/indra/newview/character/avatar_head_3.llm diff --git a/indra/newview/character/avatar_head_4.llm b/indra/newview/character/avatar_head_4.llmBinary files differ new file mode 100644 index 0000000000..5035585770 --- /dev/null +++ b/indra/newview/character/avatar_head_4.llm diff --git a/indra/newview/character/avatar_lower_body.llm b/indra/newview/character/avatar_lower_body.llmBinary files differ new file mode 100644 index 0000000000..0420899739 --- /dev/null +++ b/indra/newview/character/avatar_lower_body.llm diff --git a/indra/newview/character/avatar_lower_body_1.llm b/indra/newview/character/avatar_lower_body_1.llmBinary files differ new file mode 100644 index 0000000000..1394eb848b --- /dev/null +++ b/indra/newview/character/avatar_lower_body_1.llm diff --git a/indra/newview/character/avatar_lower_body_2.llm b/indra/newview/character/avatar_lower_body_2.llmBinary files differ new file mode 100644 index 0000000000..0da9c1249e --- /dev/null +++ b/indra/newview/character/avatar_lower_body_2.llm diff --git a/indra/newview/character/avatar_lower_body_3.llm b/indra/newview/character/avatar_lower_body_3.llmBinary files differ new file mode 100644 index 0000000000..f3c49a1568 --- /dev/null +++ b/indra/newview/character/avatar_lower_body_3.llm diff --git a/indra/newview/character/avatar_lower_body_4.llm b/indra/newview/character/avatar_lower_body_4.llmBinary files differ new file mode 100644 index 0000000000..e71721063e --- /dev/null +++ b/indra/newview/character/avatar_lower_body_4.llm diff --git a/indra/newview/character/avatar_skirt.llm b/indra/newview/character/avatar_skirt.llmBinary files differ new file mode 100644 index 0000000000..08ce3d1700 --- /dev/null +++ b/indra/newview/character/avatar_skirt.llm diff --git a/indra/newview/character/avatar_skirt_1.llm b/indra/newview/character/avatar_skirt_1.llmBinary files differ new file mode 100644 index 0000000000..88076c321f --- /dev/null +++ b/indra/newview/character/avatar_skirt_1.llm diff --git a/indra/newview/character/avatar_skirt_2.llm b/indra/newview/character/avatar_skirt_2.llmBinary files differ new file mode 100644 index 0000000000..73b3effbc6 --- /dev/null +++ b/indra/newview/character/avatar_skirt_2.llm diff --git a/indra/newview/character/avatar_skirt_3.llm b/indra/newview/character/avatar_skirt_3.llmBinary files differ new file mode 100644 index 0000000000..ded546fdea --- /dev/null +++ b/indra/newview/character/avatar_skirt_3.llm diff --git a/indra/newview/character/avatar_skirt_4.llm b/indra/newview/character/avatar_skirt_4.llmBinary files differ new file mode 100644 index 0000000000..b9d5cb945e --- /dev/null +++ b/indra/newview/character/avatar_skirt_4.llm diff --git a/indra/newview/character/avatar_upper_body.llm b/indra/newview/character/avatar_upper_body.llmBinary files differ new file mode 100644 index 0000000000..da7d990540 --- /dev/null +++ b/indra/newview/character/avatar_upper_body.llm diff --git a/indra/newview/character/avatar_upper_body_1.llm b/indra/newview/character/avatar_upper_body_1.llmBinary files differ new file mode 100644 index 0000000000..31e104cc20 --- /dev/null +++ b/indra/newview/character/avatar_upper_body_1.llm diff --git a/indra/newview/character/avatar_upper_body_2.llm b/indra/newview/character/avatar_upper_body_2.llmBinary files differ new file mode 100644 index 0000000000..c1f4199b9c --- /dev/null +++ b/indra/newview/character/avatar_upper_body_2.llm diff --git a/indra/newview/character/avatar_upper_body_3.llm b/indra/newview/character/avatar_upper_body_3.llmBinary files differ new file mode 100644 index 0000000000..9e89ed8b3e --- /dev/null +++ b/indra/newview/character/avatar_upper_body_3.llm diff --git a/indra/newview/character/avatar_upper_body_4.llm b/indra/newview/character/avatar_upper_body_4.llmBinary files differ new file mode 100644 index 0000000000..ec836d1dc3 --- /dev/null +++ b/indra/newview/character/avatar_upper_body_4.llm diff --git a/indra/newview/character/blush_alpha.tga b/indra/newview/character/blush_alpha.tgaBinary files differ new file mode 100644 index 0000000000..05be7e7e3d --- /dev/null +++ b/indra/newview/character/blush_alpha.tga diff --git a/indra/newview/character/body_skingrain.tga b/indra/newview/character/body_skingrain.tgaBinary files differ new file mode 100644 index 0000000000..7264baac14 --- /dev/null +++ b/indra/newview/character/body_skingrain.tga diff --git a/indra/newview/character/bodyfreckles_alpha.tga b/indra/newview/character/bodyfreckles_alpha.tgaBinary files differ new file mode 100644 index 0000000000..d30ab3d122 --- /dev/null +++ b/indra/newview/character/bodyfreckles_alpha.tga diff --git a/indra/newview/character/bump_face_wrinkles.tga b/indra/newview/character/bump_face_wrinkles.tgaBinary files differ new file mode 100644 index 0000000000..54bf7a55be --- /dev/null +++ b/indra/newview/character/bump_face_wrinkles.tga diff --git a/indra/newview/character/bump_head_base.tga b/indra/newview/character/bump_head_base.tgaBinary files differ new file mode 100644 index 0000000000..fa3568573a --- /dev/null +++ b/indra/newview/character/bump_head_base.tga diff --git a/indra/newview/character/bump_lowerbody_base.tga b/indra/newview/character/bump_lowerbody_base.tgaBinary files differ new file mode 100644 index 0000000000..498ea3c721 --- /dev/null +++ b/indra/newview/character/bump_lowerbody_base.tga diff --git a/indra/newview/character/bump_pants_wrinkles.tga b/indra/newview/character/bump_pants_wrinkles.tgaBinary files differ new file mode 100644 index 0000000000..cca72415e8 --- /dev/null +++ b/indra/newview/character/bump_pants_wrinkles.tga diff --git a/indra/newview/character/bump_shirt_wrinkles.tga b/indra/newview/character/bump_shirt_wrinkles.tgaBinary files differ new file mode 100644 index 0000000000..9e0d757a48 --- /dev/null +++ b/indra/newview/character/bump_shirt_wrinkles.tga diff --git a/indra/newview/character/bump_upperbody_base.tga b/indra/newview/character/bump_upperbody_base.tgaBinary files differ new file mode 100644 index 0000000000..e57d6352e6 --- /dev/null +++ b/indra/newview/character/bump_upperbody_base.tga diff --git a/indra/newview/character/eyebrows_alpha.tga b/indra/newview/character/eyebrows_alpha.tgaBinary files differ new file mode 100644 index 0000000000..c363e482e1 --- /dev/null +++ b/indra/newview/character/eyebrows_alpha.tga diff --git a/indra/newview/character/eyeliner_alpha.tga b/indra/newview/character/eyeliner_alpha.tgaBinary files differ new file mode 100644 index 0000000000..1611eb3355 --- /dev/null +++ b/indra/newview/character/eyeliner_alpha.tga diff --git a/indra/newview/character/eyeshadow_inner_alpha.tga b/indra/newview/character/eyeshadow_inner_alpha.tgaBinary files differ new file mode 100644 index 0000000000..37d7919395 --- /dev/null +++ b/indra/newview/character/eyeshadow_inner_alpha.tga diff --git a/indra/newview/character/eyeshadow_outer_alpha.tga b/indra/newview/character/eyeshadow_outer_alpha.tgaBinary files differ new file mode 100644 index 0000000000..00eef9d9f7 --- /dev/null +++ b/indra/newview/character/eyeshadow_outer_alpha.tga diff --git a/indra/newview/character/eyewhite.tga b/indra/newview/character/eyewhite.tgaBinary files differ new file mode 100644 index 0000000000..a720496988 --- /dev/null +++ b/indra/newview/character/eyewhite.tga diff --git a/indra/newview/character/facehair_chincurtains_alpha.tga b/indra/newview/character/facehair_chincurtains_alpha.tgaBinary files differ new file mode 100644 index 0000000000..b10397063c --- /dev/null +++ b/indra/newview/character/facehair_chincurtains_alpha.tga diff --git a/indra/newview/character/facehair_moustache_alpha.tga b/indra/newview/character/facehair_moustache_alpha.tgaBinary files differ new file mode 100644 index 0000000000..4068c4f2b1 --- /dev/null +++ b/indra/newview/character/facehair_moustache_alpha.tga diff --git a/indra/newview/character/facehair_sideburns_alpha.tga b/indra/newview/character/facehair_sideburns_alpha.tgaBinary files differ new file mode 100644 index 0000000000..acddc2d9bd --- /dev/null +++ b/indra/newview/character/facehair_sideburns_alpha.tga diff --git a/indra/newview/character/facehair_soulpatch_alpha.tga b/indra/newview/character/facehair_soulpatch_alpha.tgaBinary files differ new file mode 100644 index 0000000000..687091a29f --- /dev/null +++ b/indra/newview/character/facehair_soulpatch_alpha.tga diff --git a/indra/newview/character/freckles_alpha.tga b/indra/newview/character/freckles_alpha.tgaBinary files differ new file mode 100644 index 0000000000..a9a4ec0735 --- /dev/null +++ b/indra/newview/character/freckles_alpha.tga diff --git a/indra/newview/character/glove_length_alpha.tga b/indra/newview/character/glove_length_alpha.tgaBinary files differ new file mode 100644 index 0000000000..db89ad57e7 --- /dev/null +++ b/indra/newview/character/glove_length_alpha.tga diff --git a/indra/newview/character/gloves_fingers_alpha.tga b/indra/newview/character/gloves_fingers_alpha.tgaBinary files differ new file mode 100644 index 0000000000..dba2eec277 --- /dev/null +++ b/indra/newview/character/gloves_fingers_alpha.tga diff --git a/indra/newview/character/head_alpha.tga b/indra/newview/character/head_alpha.tgaBinary files differ new file mode 100644 index 0000000000..8164525353 --- /dev/null +++ b/indra/newview/character/head_alpha.tga diff --git a/indra/newview/character/head_color.tga b/indra/newview/character/head_color.tgaBinary files differ new file mode 100644 index 0000000000..74b1b3078b --- /dev/null +++ b/indra/newview/character/head_color.tga diff --git a/indra/newview/character/head_hair.tga b/indra/newview/character/head_hair.tgaBinary files differ new file mode 100644 index 0000000000..5321f35204 --- /dev/null +++ b/indra/newview/character/head_hair.tga diff --git a/indra/newview/character/head_highlights_alpha.tga b/indra/newview/character/head_highlights_alpha.tgaBinary files differ new file mode 100644 index 0000000000..8dc5239f97 --- /dev/null +++ b/indra/newview/character/head_highlights_alpha.tga diff --git a/indra/newview/character/head_shading_alpha.tga b/indra/newview/character/head_shading_alpha.tgaBinary files differ new file mode 100644 index 0000000000..e8ea490109 --- /dev/null +++ b/indra/newview/character/head_shading_alpha.tga diff --git a/indra/newview/character/head_skingrain.tga b/indra/newview/character/head_skingrain.tgaBinary files differ new file mode 100644 index 0000000000..b42dee0809 --- /dev/null +++ b/indra/newview/character/head_skingrain.tga diff --git a/indra/newview/character/jacket_length_lower_alpha.tga b/indra/newview/character/jacket_length_lower_alpha.tgaBinary files differ new file mode 100644 index 0000000000..722bc192a8 --- /dev/null +++ b/indra/newview/character/jacket_length_lower_alpha.tga diff --git a/indra/newview/character/jacket_length_upper_alpha.tga b/indra/newview/character/jacket_length_upper_alpha.tgaBinary files differ new file mode 100644 index 0000000000..e9db7e7b1f --- /dev/null +++ b/indra/newview/character/jacket_length_upper_alpha.tga diff --git a/indra/newview/character/jacket_open_lower_alpha.tga b/indra/newview/character/jacket_open_lower_alpha.tgaBinary files differ new file mode 100644 index 0000000000..db0c2fb0e3 --- /dev/null +++ b/indra/newview/character/jacket_open_lower_alpha.tga diff --git a/indra/newview/character/jacket_open_upper_alpha.tga b/indra/newview/character/jacket_open_upper_alpha.tgaBinary files differ new file mode 100644 index 0000000000..71b8a0b805 --- /dev/null +++ b/indra/newview/character/jacket_open_upper_alpha.tga diff --git a/indra/newview/character/lipgloss_alpha.tga b/indra/newview/character/lipgloss_alpha.tgaBinary files differ new file mode 100644 index 0000000000..78ceecaf85 --- /dev/null +++ b/indra/newview/character/lipgloss_alpha.tga diff --git a/indra/newview/character/lips_mask.tga b/indra/newview/character/lips_mask.tgaBinary files differ new file mode 100644 index 0000000000..ae1401c006 --- /dev/null +++ b/indra/newview/character/lips_mask.tga diff --git a/indra/newview/character/lipstick_alpha.tga b/indra/newview/character/lipstick_alpha.tgaBinary files differ new file mode 100644 index 0000000000..2795f1bd40 --- /dev/null +++ b/indra/newview/character/lipstick_alpha.tga diff --git a/indra/newview/character/lowerbody_color.tga b/indra/newview/character/lowerbody_color.tgaBinary files differ new file mode 100644 index 0000000000..a63aa12fca --- /dev/null +++ b/indra/newview/character/lowerbody_color.tga diff --git a/indra/newview/character/lowerbody_highlights_alpha.tga b/indra/newview/character/lowerbody_highlights_alpha.tgaBinary files differ new file mode 100644 index 0000000000..ae3413ac8b --- /dev/null +++ b/indra/newview/character/lowerbody_highlights_alpha.tga diff --git a/indra/newview/character/lowerbody_shading_alpha.tga b/indra/newview/character/lowerbody_shading_alpha.tgaBinary files differ new file mode 100644 index 0000000000..0242663a7d --- /dev/null +++ b/indra/newview/character/lowerbody_shading_alpha.tga diff --git a/indra/newview/character/nailpolish_alpha.tga b/indra/newview/character/nailpolish_alpha.tgaBinary files differ new file mode 100644 index 0000000000..91af762902 --- /dev/null +++ b/indra/newview/character/nailpolish_alpha.tga diff --git a/indra/newview/character/pants_length_alpha.tga b/indra/newview/character/pants_length_alpha.tgaBinary files differ new file mode 100644 index 0000000000..3c4f21c0f2 --- /dev/null +++ b/indra/newview/character/pants_length_alpha.tga diff --git a/indra/newview/character/pants_waist_alpha.tga b/indra/newview/character/pants_waist_alpha.tgaBinary files differ new file mode 100644 index 0000000000..35658c0896 --- /dev/null +++ b/indra/newview/character/pants_waist_alpha.tga diff --git a/indra/newview/character/rosyface_alpha.tga b/indra/newview/character/rosyface_alpha.tgaBinary files differ new file mode 100644 index 0000000000..a0c8513da2 --- /dev/null +++ b/indra/newview/character/rosyface_alpha.tga diff --git a/indra/newview/character/rouge_alpha.tga b/indra/newview/character/rouge_alpha.tgaBinary files differ new file mode 100644 index 0000000000..a0c8513da2 --- /dev/null +++ b/indra/newview/character/rouge_alpha.tga diff --git a/indra/newview/character/shirt_bottom_alpha.tga b/indra/newview/character/shirt_bottom_alpha.tgaBinary files differ new file mode 100644 index 0000000000..7cce03dbe0 --- /dev/null +++ b/indra/newview/character/shirt_bottom_alpha.tga diff --git a/indra/newview/character/shirt_collar_alpha.tga b/indra/newview/character/shirt_collar_alpha.tgaBinary files differ new file mode 100644 index 0000000000..f55f635473 --- /dev/null +++ b/indra/newview/character/shirt_collar_alpha.tga diff --git a/indra/newview/character/shirt_collar_back_alpha.tga b/indra/newview/character/shirt_collar_back_alpha.tgaBinary files differ new file mode 100644 index 0000000000..43a6453107 --- /dev/null +++ b/indra/newview/character/shirt_collar_back_alpha.tga diff --git a/indra/newview/character/shirt_sleeve_alpha.tga b/indra/newview/character/shirt_sleeve_alpha.tgaBinary files differ new file mode 100644 index 0000000000..e3b18f4fc6 --- /dev/null +++ b/indra/newview/character/shirt_sleeve_alpha.tga diff --git a/indra/newview/character/shoe_height_alpha.tga b/indra/newview/character/shoe_height_alpha.tgaBinary files differ new file mode 100644 index 0000000000..d08dd750f3 --- /dev/null +++ b/indra/newview/character/shoe_height_alpha.tga diff --git a/indra/newview/character/skirt_length_alpha.tga b/indra/newview/character/skirt_length_alpha.tgaBinary files differ new file mode 100644 index 0000000000..c86799469d --- /dev/null +++ b/indra/newview/character/skirt_length_alpha.tga diff --git a/indra/newview/character/skirt_slit_back_alpha.tga b/indra/newview/character/skirt_slit_back_alpha.tgaBinary files differ new file mode 100644 index 0000000000..0e49688b14 --- /dev/null +++ b/indra/newview/character/skirt_slit_back_alpha.tga diff --git a/indra/newview/character/skirt_slit_front_alpha.tga b/indra/newview/character/skirt_slit_front_alpha.tgaBinary files differ new file mode 100644 index 0000000000..888bbf71a1 --- /dev/null +++ b/indra/newview/character/skirt_slit_front_alpha.tga diff --git a/indra/newview/character/skirt_slit_left_alpha.tga b/indra/newview/character/skirt_slit_left_alpha.tgaBinary files differ new file mode 100644 index 0000000000..210feac1ea --- /dev/null +++ b/indra/newview/character/skirt_slit_left_alpha.tga diff --git a/indra/newview/character/skirt_slit_right_alpha.tga b/indra/newview/character/skirt_slit_right_alpha.tgaBinary files differ new file mode 100644 index 0000000000..ce11c64bf6 --- /dev/null +++ b/indra/newview/character/skirt_slit_right_alpha.tga diff --git a/indra/newview/character/underpants_trial_female.tga b/indra/newview/character/underpants_trial_female.tgaBinary files differ new file mode 100644 index 0000000000..96bf732351 --- /dev/null +++ b/indra/newview/character/underpants_trial_female.tga diff --git a/indra/newview/character/underpants_trial_male.tga b/indra/newview/character/underpants_trial_male.tgaBinary files differ new file mode 100644 index 0000000000..095695ca1c --- /dev/null +++ b/indra/newview/character/underpants_trial_male.tga diff --git a/indra/newview/character/undershirt_trial_female.tga b/indra/newview/character/undershirt_trial_female.tgaBinary files differ new file mode 100644 index 0000000000..e17a309531 --- /dev/null +++ b/indra/newview/character/undershirt_trial_female.tga diff --git a/indra/newview/character/upperbody_color.tga b/indra/newview/character/upperbody_color.tgaBinary files differ new file mode 100644 index 0000000000..85fcc41142 --- /dev/null +++ b/indra/newview/character/upperbody_color.tga diff --git a/indra/newview/character/upperbody_highlights_alpha.tga b/indra/newview/character/upperbody_highlights_alpha.tgaBinary files differ new file mode 100644 index 0000000000..2d8102b583 --- /dev/null +++ b/indra/newview/character/upperbody_highlights_alpha.tga diff --git a/indra/newview/character/upperbody_shading_alpha.tga b/indra/newview/character/upperbody_shading_alpha.tgaBinary files differ new file mode 100644 index 0000000000..b420506b3e --- /dev/null +++ b/indra/newview/character/upperbody_shading_alpha.tga diff --git a/indra/newview/character/upperbodyfreckles_alpha.tga b/indra/newview/character/upperbodyfreckles_alpha.tgaBinary files differ new file mode 100644 index 0000000000..76c7ce8849 --- /dev/null +++ b/indra/newview/character/upperbodyfreckles_alpha.tga diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index abe5fd8ce8..111cdf7c12 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5590,7 +5590,8 @@ void process_covenant_reply(LLMessageSystem* msg, void**)  	LLPanelLandCovenant::updateLastModified(last_modified);  	LLFloaterBuyLand::updateLastModified(last_modified); -	gCacheName->get(estate_owner_id, false, &callbackCacheEstateOwnerName); +	BOOL is_group = FALSE; +	gCacheName->get(estate_owner_id, is_group, &callbackCacheEstateOwnerName);  	// load the actual covenant asset data  	const BOOL high_priority = TRUE; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 2304571cf1..746dc99e35 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -6920,7 +6920,8 @@ void LLVoiceClient::notifyFriendObservers()  void LLVoiceClient::lookupName(const LLUUID &id)  { -	gCacheName->get(id, FALSE, &LLVoiceClient::onAvatarNameLookup); +	BOOL is_group = FALSE; +	gCacheName->get(id, is_group, &LLVoiceClient::onAvatarNameLookup);  }  //static diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index a5ee78df2c..d64fc7c8da 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -158,7 +158,7 @@ BEGIN              VALUE "FileDescription", "Second Life"              VALUE "FileVersion", "2.0.0.2425"              VALUE "InternalName", "Second Life" -            VALUE "LegalCopyright", "Copyright © 2001-2008, Linden Research, Inc." +            VALUE "LegalCopyright", "Copyright � 2001-2008, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life"              VALUE "ProductVersion", "2.0.0.2425" diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 463eedb4fd..98ad8af02d 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -14,6 +14,7 @@ include(LScript)  include(Linking)  include(Tut)  include(Boost) +include(GoogleMock)  include_directories(      ${LLCOMMON_INCLUDE_DIRS} @@ -24,6 +25,7 @@ include_directories(      ${LLVFS_INCLUDE_DIRS}      ${LLXML_INCLUDE_DIRS}      ${LSCRIPT_INCLUDE_DIRS} +    ${GOOGLEMOCK_INCLUDE_DIRS}      )  set(test_SOURCE_FILES @@ -126,6 +128,7 @@ target_link_libraries(test      ${LLXML_LIBRARIES}      ${LSCRIPT_LIBRARIES}      ${LLCOMMON_LIBRARIES} +    ${GOOGLEMOCK_LIBRARIES}      ${APRICONV_LIBRARIES}      ${PTHREAD_LIBRARY}      ${WINDOWS_LIBRARIES} @@ -145,12 +148,18 @@ endif (WINDOWS)  get_target_property(TEST_EXE test LOCATION) +SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + +SET(TEST_LD_CMD  +  ${CMAKE_COMMAND}  +  -DLD_LIBRARY_PATH=${ARCH_PREBUILT_DIRS}:/usr/lib +  -DTEST_CMD:STRING="${TEST_CMD}"  +  -P ${CMAKE_SOURCE_DIR}/cmake/RunBuildTest.cmake +  ) +  add_custom_command(    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt -  COMMAND ${TEST_EXE} -  ARGS -    --output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt -    --touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt +  COMMAND ${TEST_LD_CMD}    DEPENDS test    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}    COMMENT "C++ unit tests" diff --git a/indra/test/test.cpp b/indra/test/test.cpp index ba81c6e49e..c9e985c914 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -54,6 +54,9 @@  #	include "ctype_workaround.h"  #endif +#include <gmock/gmock.h> +#include <gtest/gtest.h> +  namespace tut  {  	std::string sSourceDir; @@ -238,6 +241,9 @@ void wouldHaveCrashed(const std::string& message)  int main(int argc, char **argv)  { +	// The following line must be executed to initialize Google Mock +	// (and Google Test) before running the tests. +	::testing::InitGoogleMock(&argc, argv);  	LLError::initForApplication(".");  	LLError::setFatalFunction(wouldHaveCrashed);  	LLError::setDefaultLevel(LLError::LEVEL_ERROR); diff --git a/install.xml b/install.xml index bffb4b2903..9b7c20a4dd 100644 --- a/install.xml +++ b/install.xml @@ -578,6 +578,39 @@            </map>          </map>        </map> +      <key>googlemock</key> +      <map> +        <key>copyright</key> +        <string>Copyright 2008, Google Inc.</string> +        <key>description</key> +        <string>Google C++ Mocking Framework (or Google Mock for short) is a library for writing and using C++ mock classes.</string> +        <key>license</key> +        <string>bsd</string> +        <key>packages</key> +        <map> +          <key>darwin</key> +          <map> +            <key>md5sum</key> +            <string>4863e9fea433d0a4be761ea5d3e8346a</string> +            <key>url</key> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-darwin-20090626.tar.bz2</uri> +          </map> +          <key>linux</key> +          <map> +            <key>md5sum</key> +            <string>877dabecf84339690191c6115c76366e</string> +            <key>url</key> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-linux32-20090527.tar.bz2</uri> +          </map> +          <key>windows</key> +          <map> +            <key>md5sum</key> +            <string>be37695d9f26552aec81c8e97ded0212</string> +            <key>url</key> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/googlemock-1.1.0-windows-20090529.tar.bz2</uri> +          </map> +        </map> +      </map>        <key>google-perftools</key>        <map>          <key>copyright</key> diff --git a/scripts/install.py b/scripts/install.py index 6278fba16c..78b8880b95 100755 --- a/scripts/install.py +++ b/scripts/install.py @@ -64,7 +64,6 @@ def add_indra_lib_path():  base_dir = add_indra_lib_path()  import copy -import md5  import optparse  import os  import platform @@ -75,7 +74,12 @@ import tempfile  import urllib2  import urlparse -from sets import Set as set, ImmutableSet as frozenset +try: +    # Python 2.6 +    from hashlib import md5 +except ImportError: +    # Python 2.5 and earlier +    from md5 import new as md5  from indra.base import llsd  from indra.util import helpformatter @@ -106,7 +110,7 @@ class InstallFile(object):          return "ifile{%s:%s}" % (self.pkgname, self.url)      def _is_md5sum_match(self): -        hasher = md5.new(file(self.filename, 'rb').read()) +        hasher = md5(file(self.filename, 'rb').read())          if hasher.hexdigest() == self.md5sum:              return  True          return False diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 67233cbda0..9deab1f857 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -5288,6 +5288,10 @@ version 2.0  		{	AgentLegacyAccess		U8	}  		{	AgentMaxAccess			U8	}  	} +	{ +		AgentInfo				Variable +		{	Flags					U32	} +	}  }  // ChildAgentAlive | 
