diff options
Diffstat (limited to 'indra')
54 files changed, 723 insertions, 564 deletions
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index bf6a4d1b21..8ee939af08 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -24,7 +24,7 @@ void ll_init_apr() apr_pool_create(&gAPRPoolp, NULL); // Initialize the logging mutex - apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_DEFAULT, gAPRPoolp); + apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); } } diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 1e2d86f814..215df520b0 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -24,6 +24,7 @@ #include "apr-1/apr_atomic.h" #include "llstring.h" +extern apr_thread_mutex_t* gLogMutexp; /** * @brief initialize the common apr constructs -- apr itself, the diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 3d9a51ecad..90ea72f24c 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -14,7 +14,6 @@ #include "llapp.h" #include "llapr.h" -extern apr_thread_mutex_t *gLogMutexp; #include "llfile.h" #include "llfixedbuffer.h" #include "lllivefile.h" diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 19b8748d2e..ca7e9590f1 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -8,6 +8,21 @@ #include "linden_common.h" +#if defined(LL_WINDOWS) +# include <windows.h> +# include <psapi.h> +#elif defined(LL_DARWIN) +# include <sys/types.h> +# include <sys/sysctl.h> +# include <mach/task.h> +# include <mach/vm_map.h> +# include <mach/mach_init.h> +# include <mach/vm_region.h> +# include <mach/mach_port.h> +#elif defined(LL_LINUX) +# include <unistd.h> +#endif + #include "llmemory.h" #include "llmemtype.h" @@ -258,3 +273,131 @@ LLRefCount::~LLRefCount() //---------------------------------------------------------------------------- +#if defined(LL_WINDOWS) + +U64 getCurrentRSS() +{ + HANDLE self = GetCurrentProcess(); + PROCESS_MEMORY_COUNTERS counters; + + if (!GetProcessMemoryInfo(self, &counters, sizeof(counters))) + { + llwarns << "GetProcessMemoryInfo failed" << llendl; + return 0; + } + + return counters.WorkingSetSize; +} + +#elif defined(LL_DARWIN) + +static U32 getPageSize() +{ + int ctl[2] = { CTL_HW, HW_PAGESIZE }; + int page_size; + size_t size = sizeof(page_size); + + if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1) + { + llwarns << "Couldn't get page size" << llendl; + return 0; + } else { + return page_size; + } +} + +U64 getCurrentRSS() +{ + task_t task = mach_task_self(); + vm_address_t addr = VM_MIN_ADDRESS; + vm_size_t size = 0; + U64 residentPages = 0; + + while (true) + { + mach_msg_type_number_t bcount = VM_REGION_BASIC_INFO_COUNT; + vm_region_basic_info binfo; + mach_port_t bobj; + kern_return_t ret; + + addr += size; + + ret = vm_region(task, &addr, &size, VM_REGION_BASIC_INFO, + (vm_region_info_t) &binfo, &bcount, &bobj); + + if (ret != KERN_SUCCESS) + { + break; + } + + if (bobj != MACH_PORT_NULL) + { + mach_port_deallocate(task, bobj); + } + + mach_msg_type_number_t ecount = VM_REGION_EXTENDED_INFO_COUNT; + vm_region_extended_info einfo; + mach_port_t eobj; + + ret = vm_region(task, &addr, &size, VM_REGION_EXTENDED_INFO, + (vm_region_info_t) &einfo, &ecount, &eobj); + + if (ret != KERN_SUCCESS) + { + llwarns << "vm_region failed" << llendl; + return 0; + } + + if (eobj != MACH_PORT_NULL) + { + mach_port_deallocate(task, eobj); + } + + residentPages += einfo.pages_resident; + } + + return residentPages * getPageSize(); +} + +#elif defined(LL_LINUX) + +U64 getCurrentRSS() +{ + static const char statPath[] = "/proc/self/stat"; + FILE *fp = fopen(statPath, "r"); + U64 rss = 0; + + if (fp == NULL) + { + llwarns << "couldn't open " << statPath << llendl; + goto bail; + } + + // Eee-yew! See Documentation/filesystems/proc.txt in your + // nearest friendly kernel tree for details. + + { + int ret = fscanf(fp, "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*d %*d " + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %Lu", + &rss); + if (ret != 1) + { + llwarns << "couldn't parse contents of " << statPath << llendl; + rss = 0; + } + } + + fclose(fp); + +bail: + return rss; +} + +#else + +U64 getCurrentRSS() +{ + return 0; +} + +#endif diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 1253d34a7d..e6a8dad83d 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -395,5 +395,8 @@ public: //---------------------------------------------------------------------------- -#endif +// Return the resident set size of the current process, in bytes. +// Return value is zero if not known. +U64 getCurrentRSS(); +#endif diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index b7be8d6a3b..424d503113 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -246,7 +246,7 @@ LLMutex::LLMutex(apr_pool_t *poolp) : mIsLocalPool = TRUE; apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread } - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_DEFAULT, mAPRPoolp); + apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); } diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index f19d85d754..b15058ad39 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -727,6 +727,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque U32* dst_pixels = (U32*) dst; U8* src = getData() + mDataOffset; + U8* last_src = src + getDataSize(); U32 rgba; U8* rgba_byte_p = (U8*) &rgba; @@ -735,6 +736,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque while( dst_pixels <= last_dst_pixel ) { // Read RLE block header + + if (src >= last_src) + return FALSE; + U8 block_header_byte = *src; src++; @@ -742,6 +747,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque if( block_header_byte & 0x80 ) { // Encoded (duplicate-pixel) block + + if (src + 3 >= last_src) + return FALSE; + rgba_byte_p[0] = src[2]; rgba_byte_p[1] = src[1]; rgba_byte_p[2] = src[0]; @@ -766,6 +775,9 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque // Unencoded block do { + if (src + 3 >= last_src) + return FALSE; + ((U8*)dst_pixels)[0] = src[2]; ((U8*)dst_pixels)[1] = src[1]; ((U8*)dst_pixels)[2] = src[0]; @@ -793,10 +805,16 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) U8* dst = raw_image->getData(); U8* src = getData() + mDataOffset; + U8* last_src = src + getDataSize(); U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1); + while( dst <= last_dst ) { // Read RLE block header + + if (src >= last_src) + return FALSE; + U8 block_header_byte = *src; src++; @@ -806,6 +824,9 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) // Encoded (duplicate-pixel) block do { + if (src + 2 >= last_src) + return FALSE; + decodeTruecolorPixel15( dst, src ); // slow dst += 3; block_pixel_count--; @@ -818,6 +839,9 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image ) // Unencoded block do { + if (src + 2 >= last_src) + return FALSE; + decodeTruecolorPixel15( dst, src ); dst += 3; src += 2; @@ -839,10 +863,16 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) U8* dst = raw_image->getData(); U8* src = getData() + mDataOffset; + U8* last_src = src + getDataSize(); U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1); + while( dst <= last_dst ) { // Read RLE block header + + if (src >= last_src) + return FALSE; + U8 block_header_byte = *src; src++; @@ -852,6 +882,8 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) // Encoded (duplicate-pixel) block do { + if (src + 2 >= last_src) + return FALSE; dst[0] = src[2]; dst[1] = src[1]; dst[2] = src[0]; @@ -866,6 +898,9 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image ) // Unencoded block do { + if (src + 2 >= last_src) + return FALSE; + dst[0] = src[2]; dst[1] = src[1]; dst[2] = src[0]; @@ -888,16 +923,25 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) U8* dst = raw_image->getData(); U8* src = getData() + mDataOffset; + U8* last_src = src + getDataSize(); U8* last_dst = dst + getHeight() * getWidth() - 1; + while( dst <= last_dst ) { // Read RLE block header + + if (src >= last_src) + return FALSE; + U8 block_header_byte = *src; src++; U8 block_pixel_count = (block_header_byte & 0x7F) + 1; if( block_header_byte & 0x80 ) { + if (src >= last_src) + return FALSE; + // Encoded (duplicate-pixel) block memset( dst, *src, block_pixel_count ); dst += block_pixel_count; @@ -908,6 +952,9 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image ) // Unencoded block do { + if (src >= last_src) + return FALSE; + *dst = *src; dst++; src++; diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index bd4bc74c79..72439531fd 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -160,84 +160,129 @@ BOOL LLXform::setParent(LLXform* parent) return TRUE; } + +// Don't blow up on release versions +#if LL_RELEASE_FOR_DOWNLOAD + #define llxformtrouble(msg, num) llwarning(msg, num) +#else + #define llxformtrouble(msg, num) llerror(msg, num) +#endif + + #ifdef CHECK_FOR_FINITE void LLXform::setPosition(const LLVector3& pos) { setChanged(TRANSLATED); if (pos.isFinite()) + { mPosition = pos; + } else - llerror("Non Finite in LLXform::setPosition(LLVector3)", 0); + { + llxformtrouble("Non Finite in LLXform::setPosition(LLVector3)", 0); + } } void LLXform::setPosition(const F32 x, const F32 y, const F32 z) { setChanged(TRANSLATED); if (llfinite(x) && llfinite(y) && llfinite(z)) + { mPosition.setVec(x,y,z); + } else - llerror("Non Finite in LLXform::setPosition(F32,F32,F32)", 0); + { + llxformtrouble("Non Finite in LLXform::setPosition(F32,F32,F32)", 0); + } } void LLXform::setPositionX(const F32 x) { setChanged(TRANSLATED); if (llfinite(x)) + { mPosition.mV[VX] = x; + } else - llerror("Non Finite in LLXform::setPositionX", 0); + { + llxformtrouble("Non Finite in LLXform::setPositionX", 0); + } } void LLXform::setPositionY(const F32 y) { setChanged(TRANSLATED); if (llfinite(y)) + { mPosition.mV[VY] = y; + } else - llerror("Non Finite in LLXform::setPositionY", 0); + { + llxformtrouble("Non Finite in LLXform::setPositionY", 0); + } } void LLXform::setPositionZ(const F32 z) { setChanged(TRANSLATED); if (llfinite(z)) + { mPosition.mV[VZ] = z; + } else - llerror("Non Finite in LLXform::setPositionZ", 0); + { + llxformtrouble("Non Finite in LLXform::setPositionZ", 0); + } } void LLXform::addPosition(const LLVector3& pos) { setChanged(TRANSLATED); if (pos.isFinite()) + { mPosition += pos; + } else - llerror("Non Finite in LLXform::addPosition", 0); + { + llxformtrouble("Non Finite in LLXform::addPosition", 0); + } } void LLXform::setScale(const LLVector3& scale) { setChanged(SCALED); if (scale.isFinite()) + { mScale = scale; + } else - llerror("Non Finite in LLXform::setScale", 0); + { + llxformtrouble("Non Finite in LLXform::setScale(LLVector)", 0); + } } void LLXform::setScale(const F32 x, const F32 y, const F32 z) { setChanged(SCALED); if (llfinite(x) && llfinite(y) && llfinite(z)) + { mScale.setVec(x,y,z); + } else - llerror("Non Finite in LLXform::setScale", 0); + { + llxformtrouble("Non Finite in LLXform::setScale(F32,F32,F32)", 0); + } } void LLXform::setRotation(const LLQuaternion& rot) { setChanged(ROTATED); if (rot.isFinite()) + { mRotation = rot; + } else - llerror("Non Finite in LLXform::setRotation", 0); + { + llxformtrouble("Non Finite in LLXform::setRotation(LLQuaternion)", 0); + } } void LLXform::setRotation(const F32 x, const F32 y, const F32 z) { @@ -248,7 +293,7 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z) } else { - llerror("Non Finite in LLXform::setRotation", 0); + llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32)", 0); } } void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) @@ -260,7 +305,7 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) } else { - llerror("Non Finite in LLXform::setRotation", 0); + llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32,F32)", 0); } } diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 23b90aef71..7b07dfd0e0 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -321,8 +321,15 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size) S32 to_read = llmin(COMPRESSED_INPUT_BUFFER_SIZE, (S32)(mVFile->getSize() - mVFile->tell())); - mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/ - + if ( to_read > 0 ) + { + mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/ + } + else + { + llwarns << "LLHTTPAssetRequest::readCompressedData has zero read length" << llendl; + break; + } mZStream.next_in = (Bytef*)mZInputBuffer; mZStream.avail_in = mVFile->getLastBytesRead(); @@ -332,7 +339,7 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size) int r = deflate(&mZStream, mZInputExhausted ? Z_FINISH : Z_NO_FLUSH); - if (r == Z_STREAM_END) + if (r == Z_STREAM_END || r < 0) { break; } @@ -345,15 +352,20 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size) size_t LLHTTPAssetRequest::curlCompressedUploadCallback( void *data, size_t size, size_t nmemb, void *user_data) { - if (!gAssetStorage) + size_t num_read = 0; + + if (gAssetStorage) { - return 0; + CURL *curl_handle = (CURL *)user_data; + LLHTTPAssetRequest *req = NULL; + curl_easy_getinfo(curl_handle, CURLINFO_PRIVATE, &req); + if (req) + { + num_read = req->readCompressedData(data, size * nmemb); + } } - CURL *curl_handle = (CURL *)user_data; - LLHTTPAssetRequest *req = NULL; - curl_easy_getinfo(curl_handle, CURLINFO_PRIVATE, &req); - return req->readCompressedData(data, size * nmemb); + return num_read; } ///////////////////////////////////////////////////////////////////////////////// @@ -511,9 +523,8 @@ void LLHTTPAssetStorage::storeAssetData( { callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); } + delete legacy; } - // Coverity CID-269 says there's a leak of 'legacy' here, but - // legacyStoreDataCallback() will delete it somewhere down the line. } // virtual diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index bfaec7c8fc..7e7d956abf 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -30,10 +30,10 @@ class LLMessageConfigFile : public LLLiveFile { public: LLMessageConfigFile() - : LLLiveFile(fileName(), messageConfigRefreshRate) + : LLLiveFile(filename(), messageConfigRefreshRate) { } - static std::string fileName(); + static std::string filename(); LLSD mMessages; std::string mServerDefault; @@ -52,7 +52,7 @@ public: LLSD mCapBans; }; -std::string LLMessageConfigFile::fileName() +std::string LLMessageConfigFile::filename() { std::ostringstream ostr; ostr << sConfigDir//gAppSimp->getOption("configdir").asString() @@ -73,9 +73,10 @@ void LLMessageConfigFile::loadFile() LLSD data; { llifstream file(filename().c_str()); + if (file.is_open()) { - llinfos << "Loading message.xml file at " << fileName() << llendl; + llinfos << "Loading message.xml file at " << filename() << llendl; LLSDSerialize::fromXML(data, file); } diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 4fa3fab1c9..c6c56218b9 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -664,8 +664,9 @@ void LLPumpIO::initialize(apr_pool_t* pool) LLMemType m1(LLMemType::MTYPE_IO_PUMP); if(!pool) return; #if LL_THREADS_APR - apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_DEFAULT, pool); - apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_DEFAULT, pool); + // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. + apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); + apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); #endif mPool = pool; } diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index c6911515a6..5077354533 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -1135,9 +1135,11 @@ LLHTTPClient::ResponderPtr LLMessageSystem::createResponder(const std::string& n } else { - llwarns << "LLMessageSystem::sendMessage: Sending unreliable " - << mMessageBuilder->getMessageName() << " message via HTTP" - << llendl; + // These messages aren't really unreliable, they just weren't + // explicitly sent as reliable, so they don't have a callback +// llwarns << "LLMessageSystem::sendMessage: Sending unreliable " +// << mMessageBuilder->getMessageName() << " message via HTTP" +// << llendl; return new LLFnPtrResponder(NULL, NULL, mMessageBuilder->getMessageName()); } diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index c130214b99..0077da1325 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -1273,9 +1273,9 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor child->getAttributeBOOL("auto_resize", auto_resize); LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child, layout_stackp, factory); - panelp->setFollowsNone(); if (panelp) { + panelp->setFollowsNone(); layout_stackp->addPanel(panelp, min_width, min_height, auto_resize); } } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ffad4809e9..5b58ba6cd3 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -600,6 +600,7 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllData() const void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) { + S32 old_height = mRect.getHeight(); LLUICtrl::reshape( width, height, called_from_parent ); S32 heading_size = (mDisplayColumnHeaders ? mHeadingHeight : 0); @@ -611,9 +612,13 @@ void LLScrollListCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; + if(old_height < height && getScrollPos() == mScrollbar->getDocPosMax()) + { + setScrollPos(mScrollbar->getDocPosMax()); + } mScrollbar->setVisible(mPageLines < getItemCount()); mScrollbar->setPageSize( mPageLines ); - + updateColumns(); } @@ -750,6 +755,7 @@ void LLScrollListCtrl::updateColumns() mColumnsIndexed.resize(mColumns.size()); std::map<LLString, LLScrollListColumn>::iterator column_itor; + bool first_dynamic = true; for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor) { LLScrollListColumn *column = &column_itor->second; @@ -761,6 +767,11 @@ void LLScrollListCtrl::updateColumns() else if (column->mDynamicWidth) { new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; + if(first_dynamic) + { + first_dynamic = false; + new_width += (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE); + } } if (new_width != column->mWidth) @@ -790,9 +801,10 @@ void LLScrollListCtrl::updateColumns() LLColumnHeader* last_header = NULL; for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it) { - if ((*column_ordered_it)->mWidth <= 0) + if ((*column_ordered_it)->mWidth < 0) { - // skip hidden columns + // skip hidden columns + continue; } LLScrollListColumn* column = *column_ordered_it; @@ -807,9 +819,8 @@ void LLScrollListCtrl::updateColumns() right += mColumnPadding; } right = llmax(left, llmin(mItemListRect.getWidth(), right)); - S32 header_width = right - left; - + last_header->reshape(header_width, mHeadingHeight); last_header->translate(left - last_header->getRect().mLeft, top - last_header->getRect().mBottom); last_header->setVisible(mDisplayColumnHeaders && header_width > 0); @@ -818,12 +829,15 @@ void LLScrollListCtrl::updateColumns() } // expand last column header we encountered to full list width + if (last_header) { S32 header_strip_width = mItemListRect.getWidth() + (mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE); S32 new_width = llmax(0, mItemListRect.mLeft + header_strip_width - last_header->getRect().mLeft); last_header->reshape(new_width, last_header->getRect().getHeight()); + last_header->setVisible(mDisplayColumnHeaders && new_width > 0); } + } void LLScrollListCtrl::setDisplayHeading(BOOL display) @@ -1433,7 +1447,9 @@ void LLScrollListCtrl::drawItems() LLGLSUIDefault gls_ui; { - LLLocalClipRect clip(mItemListRect); + LLRect clip_rect = mItemListRect; + if(!mScrollbar->getVisible()) clip_rect.mRight += SCROLLBAR_SIZE; + LLLocalClipRect clip(clip_rect); S32 cur_x = x; S32 cur_y = y; @@ -1452,10 +1468,10 @@ void LLScrollListCtrl::drawItems() item_rect.setOriginAndSize( cur_x, cur_y, - mScrollbar->getVisible() ? mItemListRect.getWidth() : mItemListRect.getWidth() + mScrollbar->getRect().getWidth(), + mScrollbar->getVisible() ? mItemListRect.getWidth() : mItemListRect.getWidth() + SCROLLBAR_SIZE, mLineHeight ); - lldebugs << mItemListRect.getWidth() << llendl; + //llinfos << item_rect.getWidth() << llendl; if (item->getSelected()) { @@ -1503,22 +1519,31 @@ void LLScrollListCtrl::drawItems() S32 cur_col = 0; S32 dynamic_width = 0; S32 dynamic_remainder = 0; + bool first_dynamic = true; if(mNumDynamicWidthColumns > 0) { dynamic_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns; dynamic_remainder = (mItemListRect.getWidth() - mTotalStaticColumnWidth) % mNumDynamicWidthColumns; } + for (LLScrollListCell* cell = item->getColumn(0); cur_col < num_cols; cell = item->getColumn(++cur_col)) { S32 cell_width = cell->getWidth(); + if(mColumnsIndexed.size() > (U32)cur_col && mColumnsIndexed[cur_col] && mColumnsIndexed[cur_col]->mDynamicWidth) { cell_width = dynamic_width + (--dynamic_remainder ? 1 : 0); + if(first_dynamic) + { + cell_width += mScrollbar->getVisible() ? 0 : SCROLLBAR_SIZE; + first_dynamic = false; + } cell->setWidth(cell_width); } // Two ways a cell could be hidden if (cell_width < 0 || !cell->getVisible()) continue; + LLUI::pushMatrix(); LLUI::translate((F32) cur_x, (F32) cur_y, 0.0f); S32 space_left = mItemListRect.mRight - cur_x; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index b8c98e1a82..d62fa2c8cc 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -2689,6 +2689,7 @@ void spawn_web_browser(const char* escaped_url) cmd += "launch_url.sh"; char* const argv[] = {(char*)cmd.c_str(), (char*)escaped_url, NULL}; + fflush(NULL); pid_t pid = fork(); if (pid == 0) { // child diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 59ebf6793a..641705da53 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -99,8 +99,6 @@ the Alpha release of the Linux client. * VOICE COMMUNICATION - this is not yet available in the Linux client. -* STREAMING MOVIES - these are currently disabled while we work on some issues. - * VISUAL EFFECTS AND PERFORMANCE - many Linux graphics drivers are not as robust as their counterparts for other operating systems, so some advanced Second Life graphical features have been DISABLED by default to aid diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index fd15f215c4..ac967c4853 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -33,6 +33,10 @@ export LL_GL_BASICEXT=x ## LL_GL_BLACKLIST which solves your problems. #export LL_GL_BLACKLIST=abcdefghijklmno + +## Everything below this line is just for advanced troubleshooters. +##------------------------------------------------------------------- + ## - For advanced debugging cases, you can run the viewer under the ## control of another program, such as strace, gdb, or valgrind. If ## you're building your own viewer, bear in mind that the executable @@ -47,6 +51,12 @@ export SDL_VIDEO_X11_DGAMOUSE=0 ## - Works around a problem with misconfigured 64-bit systems not finding GL export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri +## - The 'scim' GTK IM module widely crashes the viewer. Avoid it. +if [ "$GTK_IM_MODULE" = "scim" ]; then + export GTK_IM_MODULE=xim +fi + + ## Nothing worth editing below this line. ##------------------------------------------------------------------- diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3000cce4f9..b3dac57b2a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1838,7 +1838,7 @@ void LLAgent::cameraOrbitIn(const F32 meters) if (new_distance > max_distance) { // Unless camera is unlocked - if (!LLViewerCamera::sDisableCameraConstraints) + if (!gSavedSettings.getBOOL("DisableCameraConstraints")) { return; } @@ -3754,7 +3754,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) camera_position_global = focusPosGlobal + mCameraFocusOffset; } - if (!LLViewerCamera::sDisableCameraConstraints && !gAgent.isGodlike()) + if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike()) { LLViewerRegion* regionp = gWorldPointer->getRegionFromPosGlobal( camera_position_global); @@ -3878,7 +3878,7 @@ F32 LLAgent::getCameraMinOffGround() } else { - if (LLViewerCamera::sDisableCameraConstraints) + if (gSavedSettings.getBOOL("DisableCameraConstraints")) { return -1000.f; } diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 923a2b935a..b61be7f90d 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -21,6 +21,8 @@ #include "llpermissionsflags.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" +#include "llpreviewgesture.h" +#include "llgesturemgr.h" #include "llscrolllistctrl.h" #include "lluploaddialog.h" #include "llviewerobject.h" @@ -361,6 +363,27 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) } } break; + + case LLInventoryType::IT_GESTURE: + { + // If this gesture is active, then we need to update the in-memory + // active map with the new pointer. + if (gGestureManager.isGestureActive(item_id)) + { + LLUUID asset_id = new_item->getAssetUUID(); + gGestureManager.replaceGesture(item_id, asset_id); + gInventory.notifyObservers(); + } + + //gesture will have a new asset_id + LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id); + if(previewp) + { + previewp->onUpdateSucceeded(); + } + + } + break; case LLInventoryType::IT_WEARABLE: default: break; diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 9d83e5d80e..21407bf31a 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -50,7 +50,23 @@ void LLAudioSourceVO::updateGain() BOOL mute = FALSE; if (gParcelMgr) { - LLVector3d pos_global = mObjectp->getPositionGlobal(); + LLVector3d pos_global; + + if (mObjectp->isAttachment()) + { + LLViewerObject* parent = mObjectp; + while (parent + && !parent->isAvatar()) + { + parent = (LLViewerObject*)parent->getParent(); + } + if (parent) + pos_global = parent->getPositionGlobal(); + } + + else + pos_global = mObjectp->getPositionGlobal(); + if (!gParcelMgr->canHearSound(pos_global)) { mute = TRUE; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 22e4004d1a..d3b225b134 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -470,6 +470,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) { return; } + + if ( isMinimized() ) + { // SL looks odd if we draw the tools while the window is minimized + return; + } // Focus buttons BOOL focus_visible = ( tool == gToolCamera ); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index f0d6d2d0b1..fad7ec0c44 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -2924,12 +2924,10 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) if(selected && !on_list) { - mNumDescendantsSelected++; addToSelectionList(selection); } if(!selected && on_list) { - mNumDescendantsSelected--; removeFromSelectionList(selection); } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index af35a7211d..e15198ecb0 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -416,6 +416,19 @@ void LLGestureManager::replaceGesture(const LLUUID& item_id, LLMultiGesture* new notifyObservers(); } +void LLGestureManager::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id) +{ + item_map_t::iterator it = gGestureManager.mActive.find(item_id); + if (it == mActive.end()) + { + llwarns << "replaceGesture for inactive gesture " << item_id << llendl; + return; + } + + // mActive owns this gesture pointer, so clean up memory. + LLMultiGesture* gesture = (*it).second; + gGestureManager.replaceGesture(item_id, gesture, new_asset_id); +} void LLGestureManager::playGesture(LLMultiGesture* gesture) { diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 33d453fc30..dff2471e97 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -50,6 +50,7 @@ public: // If you change a gesture, you need to build a new multigesture // and call this method. void replaceGesture(const LLUUID& item_id, LLMultiGesture* new_gesture, const LLUUID& asset_id); + void replaceGesture(const LLUUID& item_id, const LLUUID& asset_id); // Load gesture into in-memory active form. // Can be called even if the inventory item isn't loaded yet. diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 3a873bc1a8..d57f5bf1f2 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -914,7 +914,7 @@ void LLFloaterIMPanel::init(const LLString& session_label) session_start.setArg("[NAME]", getTitle()); mSessionStartMsgPos = - mHistoryEditor->getText().length(); + mHistoryEditor->getWText().length(); addHistoryLine( session_start, @@ -966,6 +966,7 @@ BOOL LLFloaterIMPanel::postBuild() childSetAction("end_call_btn", onClickEndCall, this); childSetAction("send_btn", onClickSend, this); childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); + childSetAction("offer_tp_btn", onClickOfferTeleport, this); //LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn"); //close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this); @@ -1059,6 +1060,13 @@ void LLFloaterIMPanel::draw() childSetEnabled("start_call_btn", enable_connect); childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); + const LLRelationship* info = NULL; + info = LLAvatarTracker::instance().getBuddyInfo(mOtherParticipantUUID); + if (info) + { + childSetEnabled("offer_tp_btn", info->isOnline()); + } + if (mAutoConnect && enable_connect) { onClickStartCall(this); @@ -1385,6 +1393,13 @@ void LLFloaterIMPanel::onTabClick(void* userdata) self->setInputFocus(TRUE); } +// static +void LLFloaterIMPanel::onClickOfferTeleport(void* userdata) +{ + LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; + + handle_lure(self->mOtherParticipantUUID); +} // static void LLFloaterIMPanel::onClickProfile( void* userdata ) @@ -1646,7 +1661,7 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) //we assume the history editor hasn't moved at all since //we added the starting session message //so, we count how many characters to remove - S32 chars_to_remove = mHistoryEditor->getText().length() - + S32 chars_to_remove = mHistoryEditor->getWText().length() - mSessionStartMsgPos; mHistoryEditor->removeTextFromEnd(chars_to_remove); @@ -1744,7 +1759,7 @@ void LLFloaterIMPanel::addTypingIndicator(const std::string &name) // we may have lost a "stop-typing" packet, don't add it twice if (!mOtherTyping) { - mTypingLineStartIndex = mHistoryEditor->getText().length(); + mTypingLineStartIndex = mHistoryEditor->getWText().length(); LLUIString typing_start = sTypingStartString; typing_start.setArg("[NAME]", name); addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false); @@ -1764,7 +1779,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info) // Must do this first, otherwise addHistoryLine calls us again. mOtherTyping = FALSE; - S32 chars_to_remove = mHistoryEditor->getText().length() - mTypingLineStartIndex; + S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex; mHistoryEditor->removeTextFromEnd(chars_to_remove); if (im_info) { diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index dbe09fb396..f780bcb2bb 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -187,6 +187,7 @@ public: static void onClickProfile( void* userdata ); static void onClickGroupInfo( void* userdata ); + static void onClickOfferTeleport( void* userdata ); static void onClickClose( void* userdata ); static void onClickStartCall( void* userdata ); static void onClickEndCall( void* userdata ); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 793571e111..ead985a992 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -152,7 +152,8 @@ LLInventoryModel gInventory; // Default constructor LLInventoryModel::LLInventoryModel() : mModifyMask(LLInventoryObserver::ALL), - mLastItem(NULL) + mLastItem(NULL), + mIsAgentInvUsable(false) { } @@ -269,13 +270,9 @@ void LLInventoryModel::getDirectDescendentsOf(const LLUUID& cat_id, LLUUID LLInventoryModel::findCategoryUUIDForType(LLAssetType::EType t) { LLUUID rv = findCatUUID(t); - if(rv.isNull()) + if(rv.isNull() && isInventoryUsable()) { - rv = gAgent.getInventoryRootID(); - if(rv.notNull()) - { - rv = createNewCategory(rv, t, NULL); - } + rv = createNewCategory(rv, t, NULL); } return rv; } @@ -317,6 +314,12 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, const LLString& pname) { LLUUID id; + if(!isInventoryUsable()) + { + llwarns << "Inventory is broken." << llendl; + return id; + } + id.generate(); LLString name = pname; if(!pname.empty()) @@ -450,6 +453,16 @@ void LLInventoryModel::appendPath(const LLUUID& id, LLString& path) path.append(temp); } +bool LLInventoryModel::isInventoryUsable() +{ + bool result = false; + if(gAgent.getInventoryRootID().notNull() && mIsAgentInvUsable) + { + result = true; + } + return result; +} + // Calling this method with an inventory item will either change an // existing item with a matching item_id, or will add the item to the // current inventory. @@ -460,6 +473,13 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) { return mask; } + + if(!isInventoryUsable()) + { + llwarns << "Inventory is broken." << llendl; + return mask; + } + LLViewerInventoryItem* old_item = getItem(item->getUUID()); if(old_item) { @@ -568,6 +588,13 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) { return; } + + if(!isInventoryUsable()) + { + llwarns << "Inventory is broken." << llendl; + return; + } + LLViewerInventoryCategory* old_cat = getCategory(cat->getUUID()); if(old_cat) { @@ -625,6 +652,12 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat) void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id) { lldebugs << "LLInventoryModel::moveObject()" << llendl; + if(!isInventoryUsable()) + { + llwarns << "Inventory is broken." << llendl; + return; + } + if((object_id == cat_id) || !is_in_map(mCategoryMap, cat_id)) { llwarns << "Could not move inventory object " << object_id << " to " @@ -1066,7 +1099,7 @@ void LLInventoryModel::backgroundFetch(void*) { // finished with this category, remove from queue sFetchQueue.pop_front(); - + // add all children to queue parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID()); if (cat_it != gInventory.mParentChildCategoryTree.end()) @@ -1843,6 +1876,19 @@ void LLInventoryModel::buildParentChildMap() gAgent.sendReliableMessage(); } } + + const LLUUID& agent_inv_root_id = gAgent.getInventoryRootID(); + if (agent_inv_root_id.notNull()) + { + cat_array_t* catsp = get_ptr_in_map(mParentChildCategoryTree, agent_inv_root_id); + if(catsp) + { + // 'My Inventory', + // root of the agent's inv found. + // The inv tree is built. + mIsAgentInvUsable = true; + } + } } struct LLUUIDAndName @@ -2675,7 +2721,6 @@ void LLInventoryModel::dumpInventory() llinfos << "\n**********************\nEnd Inventory Dump" << llendl; } - ///---------------------------------------------------------------------------- /// LLInventoryCollectFunctor implementations ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 514448d1b1..7f90984659 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -142,6 +142,11 @@ public: BOOL include_trash, LLInventoryCollectFunctor& add); + // This method will return false if this inventory model is in an usabel state. + // The inventory model usage is sensitive to the initial construction of the + // model. + bool isInventoryUsable(); + // // Mutators // @@ -408,6 +413,9 @@ protected: static F32 sMinTimeBetweenFetches; static F32 sMaxTimeBetweenFetches; + // This flag is used to handle an invalid inventory state. + bool mIsAgentInvUsable; + public: // *NOTE: DEBUG functionality void dumpInventory(); @@ -777,3 +785,4 @@ protected: #endif // LL_LLINVENTORYMODEL_H + diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index af86c801ac..3ca275b9dd 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -261,7 +261,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) //Kill all particle systems owned by muted task if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT) { - gWorldPointer->mPartSim.cleanMutedParticles(localmute.mID); + gWorldPointer->mPartSim.clearParticlesByOwnerID(localmute.mID); } } return TRUE; diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index e2e283f516..fe0b488d1c 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -594,7 +594,7 @@ void LLPanelPermissions::refresh() { childSetValue("checkbox share with group",TRUE); childSetTentative("checkbox share with group",FALSE); - childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned); + childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer); } else if((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE)) { @@ -606,7 +606,7 @@ void LLPanelPermissions::refresh() { childSetValue("checkbox share with group",TRUE); childSetTentative("checkbox share with group",true); - childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned); + childSetEnabled("button deed",gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer); } } diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 0e0ade17a2..a4eac30f20 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -269,6 +269,12 @@ void LLPreviewGesture::onClose(bool app_quitting) } // virtual +void LLPreviewGesture::onUpdateSucceeded() +{ + refresh(); +} + +// virtual void LLPreviewGesture::setMinimized(BOOL minimize) { if (minimize != isMinimized()) @@ -1100,19 +1106,29 @@ void LLPreviewGesture::saveIfNeeded() file.setMaxSize(size); file.write((U8*)buffer, size); + BOOL delayedUpload = FALSE; + // Upload that asset to the database - const LLInventoryItem* item = getItem(); + LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem(); if (item) { std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory"); std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory"); if (mObjectUUID.isNull() && !agent_url.empty()) { + //need to disable the preview floater so item + //isn't re-saved before new asset arrives + //fake out refresh. + item->setComplete(FALSE); + refresh(); + item->setComplete(TRUE); + // Saving into agent inventory LLSD body; body["item_id"] = mItemUUID; LLHTTPClient::post(agent_url, body, new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE)); + delayedUpload = TRUE; } else if (!mObjectUUID.isNull() && !task_url.empty()) { @@ -1133,7 +1149,7 @@ void LLPreviewGesture::saveIfNeeded() // If this gesture is active, then we need to update the in-memory // active map with the new pointer. - if (gGestureManager.isGestureActive(mItemUUID)) + if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID)) { // gesture manager now owns the pointer gGestureManager.replaceGesture(mItemUUID, gesture, asset_id); @@ -1150,7 +1166,12 @@ void LLPreviewGesture::saveIfNeeded() } mDirty = FALSE; - refresh(); + // refresh will be called when callback + // if triggered when delayedUpload + if(!delayedUpload) + { + refresh(); + } } delete [] buffer; diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index 2a122c202c..3f0a110ff7 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -44,6 +44,7 @@ public: virtual BOOL canClose(); virtual void setMinimized(BOOL minimize); virtual void onClose(bool app_quitting); + virtual void onUpdateSucceeded(); protected: diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 57a6069aff..4e456b0a65 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1643,7 +1643,6 @@ LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name, setTitle(title); - } LLLiveLSLEditor::~LLLiveLSLEditor() @@ -1695,9 +1694,8 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) { // HACK! we "know" that mItemID refers to a LLViewerInventoryItem... LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(mItemID); - if(item - && (gAgent.allowOperation(PERM_COPY, item->getPermissions(), - GP_OBJECT_MANIPULATE) + if(item + && (gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE) || gAgent.isGodlike())) { mItem = new LLViewerInventoryItem(item); @@ -1706,12 +1704,10 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) if(!gAgent.isGodlike() && (item - && (!gAgent.allowOperation(PERM_COPY, item->getPermissions(), - GP_OBJECT_MANIPULATE) - || !gAgent.allowOperation(PERM_MODIFY, - item->getPermissions(), GP_OBJECT_MANIPULATE)))) - + && (!gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE) + || !gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))) { + mItem = new LLViewerInventoryItem(item); mScriptEd->mEditor->setText("You are not allowed to view this script."); mScriptEd->mEditor->makePristine(); mScriptEd->mEditor->setEnabled(FALSE); @@ -1769,6 +1765,20 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) gMessageSystem->sendReliable(host); */ } + + // Initialization of the asset failed. Probably the result + // of a bug somewhere else. Set up this editor in a no-go mode. + if(mItem.isNull()) + { + // Set the inventory item to an incomplete item. + // This may be better than having a accessible null pointer around, + // though this newly allocated object will most likely be replaced. + mItem = new LLViewerInventoryItem(); + mScriptEd->mEditor->setText(""); + mScriptEd->mEditor->makePristine(); + mScriptEd->mEditor->setEnabled(FALSE); + mAssetStatus = PREVIEW_ASSET_LOADED; + } } else { @@ -2016,6 +2026,14 @@ void LLLiveLSLEditor::saveIfNeeded() return; } + if(mItem.isNull() || !mItem->isComplete()) + { + // $NOTE: While the error message may not be exactly correct, + // it's pretty close. + gViewerWindow->alertXml("SaveScriptFailObjectNotFound"); + return; + } + // get the latest info about it. We used to be losing the script // name on save, because the viewer object version of the item, // and the editor version would get out of synch. Here's a good @@ -2279,6 +2297,11 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use delete data; } +void LLLiveLSLEditor::open() +{ + LLFloater::open(); /*Flawfinder: ignore*/ +} + BOOL LLLiveLSLEditor::canClose() { return (mScriptEd->canClose()); diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 444bb629e6..d0e7849f5c 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -193,6 +193,9 @@ public: bool is_script_running); virtual void callbackLSLCompileFailed(const LLSD& compile_errors); + // Overide LLPreview::open() to avoid calling loadAsset twice. + /*virtual*/ void open(); /*Flawfinder: ignore*/ + protected: virtual BOOL canClose(); void closeIfNeeded(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2e67112e3e..bfb46301c2 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -4170,11 +4170,21 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name, switch(send_type) { case SEND_ONLY_ROOTS: - node = mSelectedObjects->getFirstRootNode(); - while(node) { - nodes_to_send.push(node); - node = mSelectedObjects->getNextRootNode(); + node = mSelectedObjects->getFirstRootNode(); + + while(node) + { + // look and see if this object is actually modifiable by the current agent, because if it's not, then there's little + // point in pushing it up to the server to be updated, since we couldn't change it anywa. + // That just results in errors on screen when this function gets called by other things, like pulling down a drop down menu + LLViewerObject* object = node->getObject(); + if( object && (object->permModify() || gAgent.allowOperation(PERM_MODIFY, *node->mPermissions) || gAgent.allowOperation(PERM_MOVE, *node->mPermissions))) + { + nodes_to_send.push(node); + } + node = mSelectedObjects->getNextRootNode(); + } } break; case SEND_INDIVIDUALS: diff --git a/indra/newview/llsrv.cpp b/indra/newview/llsrv.cpp index 7669eb994a..07f14f780e 100644 --- a/indra/newview/llsrv.cpp +++ b/indra/newview/llsrv.cpp @@ -9,347 +9,25 @@ #include "llviewerprecompiledheaders.h" #include "llsrv.h" +#include "llares.h" -using namespace std; - -#if LL_WINDOWS - -#undef UNICODE -#include <winsock2.h> -#include <windns.h> - -vector<LLSRVRecord> LLSRV::query(const string& name) +struct Responder : public LLAres::UriRewriteResponder { - vector<LLSRVRecord> recs; - DNS_RECORD *rec; - DNS_STATUS status; - - status = DnsQuery(name.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &rec, NULL); - if (!status) - { - for (DNS_RECORD *cur = rec; cur != NULL; cur = cur->pNext) + std::vector<std::string> mUris; + void rewriteResult(const std::vector<std::string> &uris) { + for (size_t i = 0; i < uris.size(); i++) { - if (cur->wType != DNS_TYPE_SRV) - { - continue; - } - recs.push_back(LLSRVRecord(cur->Data.Srv.wPriority, - cur->Data.Srv.wWeight, - cur->Data.Srv.pNameTarget, - cur->Data.Srv.wPort)); + llinfos << "[" << i << "] " << uris[i] << llendl; } - DnsRecordListFree(rec, DnsFreeRecordListDeep); + mUris = uris; } +}; - return recs; -} - -#else // !LL_WINDOWS - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/nameser_compat.h> -#include <resolv.h> - -#include <netdb.h> - -#ifdef HOMEGROWN_RESPONSE_PARSER - -// We ought to be using libresolv's ns_initparse and ns_parserr to -// parse the result of our query. However, libresolv isn't packaged -// correctly on Linux (as of BIND 9), so neither of these functions is -// available without statically linking against libresolv. Ugh! This -// fallback function is available if we need to parse the response -// ourselves without relying too much on libresolv. It is NOT THE -// DEFAULT. - -vector<LLSRVRecord> LLSRV::parseResponse(const unsigned char *response, - int resp_len) +std::vector<std::string> LLSRV::rewriteURI(const std::string& uri) { - vector<LLSRVRecord> recs; - - const unsigned char *pos = response + sizeof(HEADER); - const unsigned char *end = response + resp_len; - const HEADER *hdr = (const HEADER *) response; - char name[1024]; - - // Skip over the query embedded in the response. - - for (int q = ntohs(hdr->qdcount); q > 0; --q) - { - int len = dn_expand(response, end, pos, name, sizeof(name)); - - if (len == -1) - { - llinfos << "Could not expand queried name in RR response" - << llendl; - goto bail; - } - - pos += len + NS_QFIXEDSZ; - } - - for (int a = ntohs(hdr->ancount); a > 0; --a) - { - static const ns_rr *rr; - - int len = dn_expand(response, end, pos, name, sizeof(name) - 1); - if (len == -1) - { - llinfos << "Could not expand response name in RR response" - << llendl; - goto bail; - } - - // Skip over the resource name and headers we don't care about. - - pos += len + sizeof(rr->type) + sizeof(rr->rr_class) + - sizeof(rr->ttl) + sizeof(rr->rdlength); - - U16 prio; - U16 weight; - U16 port; - - NS_GET16(prio, pos); - NS_GET16(weight, pos); - NS_GET16(port, pos); - - len = dn_expand(response, end, pos, name, sizeof(name) - 1); - - if (len == -1) - { - llinfos << "Could not expand name in RR response" << llendl; - goto bail; - } - - recs.push_back(LLSRVRecord(prio, weight, name, port)); - } - - // There are likely to be more records in the response, but we - // don't care about those, at least for now. -bail: - return reorder(recs); -} - -#else // HOMEGROWN_RESPONSE_PARSER - -// This version of the response parser is the one to use if libresolv -// is available and behaving itself. - -vector<LLSRVRecord> LLSRV::parseResponse(const unsigned char *response, - int resp_len) -{ - vector<LLSRVRecord> recs; - ns_msg hdr; - - if (ns_initparse(response, resp_len, &hdr)) - { - llinfos << "Could not parse response" << llendl; - goto bail; - } - - for (int i = 0; i < ns_msg_count(hdr, ns_s_an); i++) - { - ns_rr rr; - - if (ns_parserr(&hdr, ns_s_an, i, &rr)) - { - llinfos << "Could not parse RR" << llendl; - goto bail; - } - - if (ns_rr_type(rr) != ns_t_srv) - { - continue; - } - - const unsigned char *pos = ns_rr_rdata(rr); - U16 prio, weight, port; - char name[1024]; - int ret; - - NS_GET16(prio, pos); - NS_GET16(weight, pos); - NS_GET16(port, pos); - - ret = dn_expand(ns_msg_base(hdr), ns_msg_end(hdr), pos, - name, sizeof(name)); - - if (ret == -1) - { - llinfos << "Could not decompress name" << llendl; - goto bail; - } - - recs.push_back(LLSRVRecord(prio, weight, name, port)); - } - -bail: - return reorder(recs); -} - -#endif // HOMEGROWN_RESPONSE_PARSER - -vector<LLSRVRecord> LLSRV::query(const string& queryName) -{ - unsigned char response[16384]; - vector<LLSRVRecord> recs; - int len; - - len = res_query(queryName.c_str(), ns_c_in, ns_t_srv, response, - sizeof(response)); - - if (len == -1) - { - llinfos << "Query failed for " << queryName << llendl; - goto bail; - } - else if (len > (int) sizeof(response)) - { - llinfos << "Response too big for " << queryName - << " (capacity " << sizeof(response) - << ", response " << len << ")" << llendl; - goto bail; - } - - recs = parseResponse(response, len); -bail: - return reorder(recs); -} - -#endif // LL_WINDOWS - -// Implement the algorithm specified in RFC 2782 for dealing with RRs -// of differing priorities and weights. -vector<LLSRVRecord> LLSRV::reorder(vector<LLSRVRecord>& recs) -{ - typedef list<const LLSRVRecord *> reclist_t; - typedef map<U16, reclist_t> bucket_t; - vector<LLSRVRecord> newRecs; - bucket_t buckets; - - // Don't rely on the DNS server to shuffle responses. - - random_shuffle(recs.begin(), recs.end()); - - for (vector<LLSRVRecord>::const_iterator iter = recs.begin(); - iter != recs.end(); ++iter) - { - buckets[iter->priority()].push_back(&*iter); - } - - // Priorities take precedence over weights. - - for (bucket_t::iterator iter = buckets.begin(); - iter != buckets.end(); ++iter) - { - reclist_t& myPrio = iter->second; - reclist_t r; - - // RRs with weight zero go to the front of the intermediate - // list, so they'll have little chance of being chosen. - // Larger weights have a higher likelihood of selection. - - for (reclist_t::iterator i = myPrio.begin(); i != myPrio.end(); ) - { - if ((*i)->weight() == 0) - { - r.push_back(*i); - i = myPrio.erase(i); - } else { - ++i; - } - } - - r.insert(r.end(), myPrio.begin(), myPrio.end()); - - while (!r.empty()) - { - U32 total = 0; - - for (reclist_t::const_iterator i = r.begin(); i != r.end(); ++i) - { - total += (*i)->weight(); - } - - U32 target = total > 1 ? (rand() % total) : 0; - U32 partial = 0; - - for (reclist_t::iterator i = r.begin(); i != r.end(); ) - { - partial += (*i)->weight(); - if (partial >= target) - { - newRecs.push_back(**i); - i = r.erase(i); - } else { - ++i; - } - } - } - } - - // Order RRs by lowest numeric priority. The stable sort - // preserves the weight choices we made above. - - stable_sort(newRecs.begin(), newRecs.end(), - LLSRVRecord::ComparePriorityLowest()); - - return newRecs; -} - -vector<string> LLSRV::rewriteURI(const string& uriStr) -{ - LLURI uri(uriStr); - const string& scheme = uri.scheme(); - llinfos << "Rewriting " << uriStr << llendl; - string serviceName("_" + scheme + "._tcp." + uri.hostName()); - llinfos << "Querying for " << serviceName << llendl; - vector<LLSRVRecord> srvs(LLSRV::query(serviceName)); - vector<string> rewritten; - - if (srvs.empty()) - { - llinfos << "No query results; using " << uriStr << llendl; - rewritten.push_back(uriStr); - } - else - { - vector<LLSRVRecord>::const_iterator iter; - size_t maxSrvs = 3; - size_t i; - - llinfos << "Got " << srvs.size() << " results" << llendl; - for (iter = srvs.begin(); iter != srvs.end(); ++iter) - { - lldebugs << "host " << iter->target() << ':' << iter->port() - << " prio " << iter->priority() - << " weight " << iter->weight() - << llendl; - } - - if (srvs.size() > maxSrvs) - { - llinfos << "Clamping to " << maxSrvs << llendl; - } - - for (iter = srvs.begin(), i = 0; - iter != srvs.end() && i < maxSrvs; ++iter, ++i) - { - LLURI newUri(scheme, - uri.userName(), - uri.password(), - iter->target(), - uri.defaultPort() ? iter->port() : uri.hostPort(), - uri.escapedPath(), - uri.escapedQuery()); - string newUriStr(newUri.asString()); - - llinfos << "Rewrite[" << i << "] " << newUriStr << llendl; - - rewritten.push_back(newUriStr); - } - } + LLPointer<Responder> resp = new Responder; - return rewritten; + gAres->rewriteURI(uri, resp); + gAres->processAll(); + return resp->mUris; } diff --git a/indra/newview/llsrv.h b/indra/newview/llsrv.h index fde4f3915d..9876f36ce7 100644 --- a/indra/newview/llsrv.h +++ b/indra/newview/llsrv.h @@ -9,52 +9,9 @@ #ifndef LL_LLSRV_H #define LL_LLSRV_H -class LLSRV; - -class LLSRVRecord -{ - friend class LLSRV; - -protected: - U16 mPriority; - U16 mWeight; - std::string mTarget; - U16 mPort; - -public: - LLSRVRecord(U16 priority, U16 weight, const std::string& target, - U16 port) : - mPriority(priority), - mWeight(weight), - mTarget(target), - mPort(port) { - } - - U16 priority() const { return mPriority; } - U16 weight() const { return mWeight; } - const std::string& target() const { return mTarget; } - U16 port() const { return mPort; } - - struct ComparePriorityLowest - { - bool operator()(const LLSRVRecord& lhs, const LLSRVRecord& rhs) - { - return lhs.mPriority < rhs.mPriority; - } - }; -}; - class LLSRV { -protected: -#ifndef LL_WINDOWS - static std::vector<LLSRVRecord> parseResponse(const unsigned char *response, - int resp_len); -#endif - static std::vector<LLSRVRecord> reorder(std::vector<LLSRVRecord>& recs); - public: - static std::vector<LLSRVRecord> query(const std::string& name); static std::vector<std::string> rewriteURI(const std::string& uri); }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8aa442818e..8767b15715 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -23,6 +23,7 @@ #endif #include "audiosettings.h" +#include "llares.h" #include "llcachename.h" #include "llviewercontrol.h" #include "lldir.h" @@ -53,7 +54,6 @@ #include "llagent.h" #include "llagentpilot.h" -#include "llasynchostbyname.h" #include "llfloateravatarpicker.h" #include "llcallbacklist.h" #include "llcallingcard.h" @@ -269,6 +269,9 @@ void update_texture_fetch() gImageList.updateImages(0.10f); } +static std::vector<std::string> sAuthUris; +static int sAuthUriNum = -1; + // Returns FALSE to skip other idle processing. Should only return // TRUE when all initialization done. BOOL idle_startup() @@ -287,8 +290,6 @@ BOOL idle_startup() // auth/transform loop will do. static F32 progress = 0.10f; - static std::vector<std::string> auth_uris; - static int auth_uri_num = -1; static std::string auth_method; static std::string auth_desc; static std::string auth_message; @@ -402,6 +403,11 @@ BOOL idle_startup() // Load the throttle settings gViewerThrottle.load(); + if (ll_init_ares() == NULL) + { + llerrs << "Could not start address resolution system" << llendl; + } + // // Initialize messaging system // @@ -548,7 +554,10 @@ BOOL idle_startup() #endif // LL_LINUX std::ostringstream codec; - codec << "[Second Life " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD << "]"; + codec << "[Second Life "; + codec << "(" << gChannelName << ")"; + codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; + codec << "]"; LLMozLib::getInstance()->setBrowserAgentId( codec.str() ); #endif @@ -758,7 +767,7 @@ BOOL idle_startup() if ( user_picked_server ) { // User picked a grid from the popup, so clear the stored urls and they will be re-generated from gUserServerChoice - auth_uris.clear(); + sAuthUris.clear(); resetURIs(); } @@ -872,11 +881,11 @@ BOOL idle_startup() gSavedSettings.setBOOL("UseDebugMenus", TRUE); requested_options.push_back("god-connect"); } - if (auth_uris.empty()) + if (sAuthUris.empty()) { - auth_uris = getLoginURIs(); + sAuthUris = getLoginURIs(); } - auth_uri_num = 0; + sAuthUriNum = 0; auth_method = "login_to_simulator"; auth_desc = "Logging in. "; auth_desc += gSecondLife; @@ -919,7 +928,7 @@ BOOL idle_startup() hashed_mac.hex_digest(hashed_mac_string); gUserAuthp->authenticate( - auth_uris[auth_uri_num].c_str(), + sAuthUris[sAuthUriNum].c_str(), auth_method.c_str(), firstname.c_str(), lastname.c_str(), @@ -1015,8 +1024,8 @@ BOOL idle_startup() else if(login_response && (0 == strcmp(login_response, "indeterminate"))) { llinfos << "Indeterminate login..." << llendl; - auth_uris = LLSRV::rewriteURI(gUserAuthp->getResponse("next_url")); - auth_uri_num = 0; + sAuthUris = LLSRV::rewriteURI(gUserAuthp->getResponse("next_url")); + sAuthUriNum = 0; auth_method = gUserAuthp->getResponse("next_method"); auth_message = gUserAuthp->getResponse("message"); if(auth_method.substr(0, 5) == "login") @@ -1121,18 +1130,18 @@ BOOL idle_startup() case LLUserAuth::E_SSL_CACERT: case LLUserAuth::E_SSL_CONNECT_ERROR: default: - if (auth_uri_num >= (int) auth_uris.size() - 1) + if (sAuthUriNum >= (int) sAuthUris.size() - 1) { emsg << "Unable to connect to " << gSecondLife << ".\n"; emsg << gUserAuthp->errorMessage(); } else { - auth_uri_num++; + sAuthUriNum++; std::ostringstream s; s << "Previous login attempt failed. Logging in, attempt " - << (auth_uri_num + 1) << ". "; + << (sAuthUriNum + 1) << ". "; auth_desc = s.str(); LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE ); - auth_uri_num++; + sAuthUriNum++; return do_normal_idle; } break; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index da93aced1f..3719e34a2c 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -25,8 +25,6 @@ #include "llvovolume.h" #include "llworld.h" -BOOL LLViewerCamera::sDisableCameraConstraints = FALSE; - LLViewerCamera *gCamera = NULL; LLViewerCamera::LLViewerCamera() : LLCamera() diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index b28aac269b..b08902ca04 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -83,7 +83,6 @@ protected: S16 mZoomSubregion; public: - static BOOL sDisableCameraConstraints; F64 mGLProjectionMatrix[16]; }; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0fea0ffb30..21a334e70b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -748,9 +748,12 @@ void init_client_menu(LLMenuGL* menu) NULL, &menu_check_control, (void*)"HighResSnapshot")); - - menu->append(new LLMenuItemToggleGL("Quiet Snapshots to Disk", - &gQuietSnapshot)); + + menu->append(new LLMenuItemCheckGL( "Quiet Snapshots to Disk", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"QuietSnapshotsToDisk")); menu->append(new LLMenuItemCheckGL( "Compress Snapshots to Disk", &menu_toggle_control, @@ -877,8 +880,11 @@ void init_client_menu(LLMenuGL* menu) &menu_check_control, (void*)"LimitSelectDistance")); - menu->append(new LLMenuItemToggleGL("Disable Camera Constraints", - &LLViewerCamera::sDisableCameraConstraints, 'C', MASK_ALT | MASK_CONTROL )); + menu->append(new LLMenuItemCheckGL("Disable Camera Constraints", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"DisableCameraConstraints")); menu->append(new LLMenuItemCheckGL("Joystick Flycam", &handle_toggle_flycam,NULL,&check_flycam,NULL)); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 9d8a4b0026..38c6e22b7b 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -379,7 +379,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t gSavedSettings.getBOOL("RenderUIInSnapshot"), FALSE)) { - if (!gQuietSnapshot) + if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) { gViewerWindow->playSnapshotAnimAndSound(); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f907ac698e..c09dd03dd4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1084,7 +1084,7 @@ void inventory_offer_callback(S32 button, void* user_data) // Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED, // or IM_GROUP_NOTICE_INVENTORY_DECLINED default: - // close button probably + // close button probably (or any of the fall-throughs from above) msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2)); msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE); // send the message @@ -1119,7 +1119,7 @@ void inventory_offer_callback(S32 button, void* user_data) } } - if (busy || (!info->mFromGroup && !info->mFromObject)) + if (busy && (!info->mFromGroup && !info->mFromObject)) { busy_message(msg,info->mFromID); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index fb8d7af004..72eab6555b 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -625,6 +625,29 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) return ret; } +// Show or hide particles, icon and HUD +void LLViewerObject::hideExtraDisplayItems( BOOL hidden ) +{ + if( mPartSourcep.notNull() ) + { + LLViewerPartSourceScript *partSourceScript = mPartSourcep.get(); + partSourceScript->setSuspended( hidden ); + } + + if( mText.notNull() ) + { + LLHUDText *hudText = mText.get(); + hudText->setHidden( hidden ); + } + + if( mIcon.notNull() ) + { + LLHUDIcon *hudIcon = mIcon.get(); + hudIcon->setHidden( hidden ); + } +} + + U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -1576,23 +1599,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, sent_parentp->addChild(this); } - if( mPartSourcep.notNull() ) - { - LLViewerPartSourceScript *partSourceScript = mPartSourcep.get(); - partSourceScript->setSuspended( FALSE ); - } - - if( mText.notNull() ) - { - LLHUDText *hudText = mText.get(); - hudText->setHidden( FALSE ); - } - - if( mIcon.notNull() ) - { - LLHUDIcon *hudIcon = mIcon.get(); - hudIcon->setHidden( FALSE ); - } + // Show particles, icon and HUD + hideExtraDisplayItems( FALSE ); setChanged(MOVED | SILHOUETTE); } @@ -1608,23 +1616,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U32 port = mesgsys->getSenderPort(); gObjectList.orphanize(this, parent_id, ip, port); - if( mPartSourcep.notNull() ) - { - LLViewerPartSourceScript *partSourceScript = mPartSourcep.get(); - partSourceScript->setSuspended( TRUE ); - } - - if( mText.notNull() ) - { - LLHUDText *hudText = mText.get(); - hudText->setHidden( TRUE ); - } - if( mIcon.notNull() ) - { - LLHUDIcon *hudIcon = mIcon.get(); - hudIcon->setHidden( TRUE ); - } + // Hide particles, icon and HUD + hideExtraDisplayItems( TRUE ); } } } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1ec3c4c6bc..4b35876d78 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -517,6 +517,9 @@ protected: BOOL setData(const U8 *datap, const U32 data_size); + // Hide or show HUD, icon and particles + void hideExtraDisplayItems( BOOL hidden ); + ////////////////////////// // // inventory functionality diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index b029e60422..204a22eb79 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1439,6 +1439,10 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE); childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans() } + + // Make certain particles, icon and HUD aren't hidden + childp->hideExtraDisplayItems( FALSE ); + objectp->addChild(childp); orphans_found = TRUE; } diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 476326147c..940826f331 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -397,6 +397,18 @@ void LLViewerPartGroup::shift(const LLVector3 &offset) } } +void LLViewerPartGroup::removeParticlesByID(const U32 source_id) +{ + LLMemType mt(LLMemType::MTYPE_PARTICLES); + S32 end = (S32) mParticles.size(); + for (int i = 0; i < end; i++) + { + if(mParticles[i]->mPartSourcep->getID() == source_id) + { + mParticles[i]->mFlags = LLViewerPart::LL_PART_DEAD_MASK; + } + } +} ////////////////////////////////// // @@ -664,6 +676,10 @@ void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep) mViewerPartSources.push_back(sourcep); } +void LLViewerPartSim::removeLastCreatedSource() +{ + mViewerPartSources.pop_back(); +} void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) { @@ -680,16 +696,32 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp) } } -void LLViewerPartSim::cleanMutedParticles(const LLUUID& task_id) +void LLViewerPartSim::clearParticlesByID(const U32 system_id) { LLMemType mt(LLMemType::MTYPE_PARTICLES); - for (source_list_t::iterator i = mViewerPartSources.begin(); i != mViewerPartSources.end(); ) + for (group_list_t::iterator g = mViewerPartGroups.begin(); g != mViewerPartGroups.end(); ++g) { - source_list_t::iterator iter = i++; + (*g)->removeParticlesByID(system_id); + } + for (source_list_t::iterator i = mViewerPartSources.begin(); i != mViewerPartSources.end(); ++i) + { + if ((*i)->getID() == system_id) + { + (*i)->setDead(); + break; + } + } + +} +void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id) +{ + LLMemType mt(LLMemType::MTYPE_PARTICLES); + for (source_list_t::iterator iter = mViewerPartSources.begin(); iter != mViewerPartSources.end(); ++iter) + { if ((*iter)->getOwnerUUID() == task_id) { - i = mViewerPartSources.erase(iter); + clearParticlesByID((*iter)->getID()); } } } diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index afde3049f7..f90d78e08b 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -87,6 +87,8 @@ public: S32 getCount() const { return (S32) mParticles.size(); } LLViewerRegion *getRegion() const { return mRegionp; } + void removeParticlesByID(const U32 source_id); + LLPointer<LLVOPartGroup> mVOPartGroupp; BOOL mUniformParticles; @@ -106,10 +108,14 @@ protected: class LLViewerPartSim { + public: LLViewerPartSim(); virtual ~LLViewerPartSim(); + typedef std::vector<LLViewerPartGroup *> group_list_t; + typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t; + void shift(const LLVector3 &offset); void updateSimulation(); @@ -120,7 +126,11 @@ public: BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping) void addPart(LLViewerPart* part); - void cleanMutedParticles(const LLUUID& task_id); + void clearParticlesByID(const U32 system_id); + void clearParticlesByOwnerID(const LLUUID& task_id); + void removeLastCreatedSource(); + + const source_list_t* getParticleSystemList() const { return &mViewerPartSources; } friend class LLViewerPartGroup; @@ -138,8 +148,6 @@ protected: LLViewerPartGroup *put(LLViewerPart* part); protected: - typedef std::vector<LLViewerPartGroup *> group_list_t; - typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t; group_list_t mViewerPartGroups; source_list_t mViewerPartSources; LLFrameTimer mSimulationTimer; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 414d94e8ad..4d640e5e59 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -47,7 +47,15 @@ void LLViewerPartSource::update(const F32 dt) llerrs << "Creating default part source!" << llendl; } - +LLUUID LLViewerPartSource::getImageUUID() const +{ + LLViewerImage* imagep = mImagep; + if(imagep) + { + return imagep->getID(); + } + return LLUUID::null; +} LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) : LLViewerPartSource(LL_PART_SOURCE_SCRIPT) diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h index 807f73e2ab..09f7f807be 100644 --- a/indra/newview/llviewerpartsource.h +++ b/indra/newview/llviewerpartsource.h @@ -48,6 +48,8 @@ public: static void updatePart(LLViewerPart &part, const F32 dt); void setOwnerUUID(const LLUUID& owner_id) { mOwnerUUID = owner_id; } LLUUID getOwnerUUID() const { return mOwnerUUID; } + U32 getID() const { return mID; } + LLUUID getImageUUID() const; LLVector3 mPosAgent; // Location of the particle source LLVector3 mTargetPosAgent; // Location of the target position @@ -62,7 +64,8 @@ protected: F32 mLastUpdateTime; F32 mLastPartTime; LLUUID mOwnerUUID; - + LLPointer<LLViewerImage> mImagep; + // Particle information U32 mPartFlags; // Flags for the particle }; @@ -100,7 +103,6 @@ public: protected: LLQuaternion mRotation; // Current rotation for particle source - LLPointer<LLViewerImage> mImagep; // Cached image pointer of the mPartSysData UUID LLPointer<LLViewerObject> mTargetObjectp; // Target object for the particle source }; @@ -125,7 +127,6 @@ public: static void updatePart(LLViewerPart &part, const F32 dt); LLColor4 mColor; protected: - LLPointer<LLViewerImage> mImagep; LLVector3d mLKGSourcePosGlobal; }; @@ -151,7 +152,6 @@ public: void setColor(const LLColor4 &color); static void updatePart(LLViewerPart &part, const F32 dt); - LLPointer<LLViewerImage> mImagep; LLPointer<LLViewerObject> mTargetObjectp; LLVector3d mLKGTargetPosGlobal; LLColor4 mColor; @@ -177,11 +177,9 @@ public: void setSourceObject(LLViewerObject *objp); void setColor(const LLColor4 &color); - static void updatePart(LLViewerPart &part, const F32 dt); LLColor4 mColor; protected: - LLPointer<LLViewerImage> mImagep; LLVector3d mLKGSourcePosGlobal; }; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index bb60c8283e..1bc9616bcc 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -365,7 +365,6 @@ void reset_viewer_state_on_sim(void); extern LLVelocityBar* gVelocityBar; extern LLViewerWindow* gViewerWindow; -extern BOOL gQuietSnapshot; extern LLFrameTimer gMouseIdleTimer; // how long has it been since the mouse last moved? extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar away state to true diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 95a5b140f6..8ff40a297a 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1361,7 +1361,7 @@ void LLVoiceClient::stateMachine() sGatewayPID = id; } #endif // LL_WINDOWS - mDaemonHost = LLHost("127.0.0.1", 44124); + mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort")); } else { @@ -1374,7 +1374,7 @@ void LLVoiceClient::stateMachine() // To do this, launch the gateway on a nearby host like this: // vivox-gw.exe -p tcp -i 0.0.0.0:44124 // and put that host's IP address here. - mDaemonHost = LLHost("127.0.0.1", 44124); + mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort")); } mUpdateTimer.start(); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a20ebece11..6b38bd1765 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -258,7 +258,7 @@ class WindowsManifest(ViewerManifest): if self.default_channel(): if self.default_grid(): # release viewer - installer_file = "Second Life %(version_dashes)s Setup.exe" + installer_file = "Second_Life_%(version_dashes)s_Setup.exe" grid_vars_template = """ OutFile "%(installer_file)s" !define INSTFLAGS "%(flags)s" @@ -269,7 +269,7 @@ class WindowsManifest(ViewerManifest): """ else: # beta grid viewer - installer_file = "Second Life %(version_dashes)s (%(grid_caps)s) Setup.exe" + installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe" grid_vars_template = """ OutFile "%(installer_file)s" !define INSTFLAGS "%(flags)s" @@ -281,7 +281,7 @@ class WindowsManifest(ViewerManifest): """ else: # some other channel on some grid - installer_file = "Second Life %(version_dashes)s %(channel_unique)s Setup.exe" + installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe" grid_vars_template = """ OutFile "%(installer_file)s" !define INSTFLAGS "%(flags)s" @@ -475,11 +475,6 @@ class Linux_i686Manifest(LinuxManifest): self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") self.path("libdb-4.2.so") - self.path("libogg.so.0") - self.path("libvorbis.so.0") - self.path("libvorbisfile.so.0") - self.path("libvorbisenc.so.0") - self.path("libcurl.so.4") self.path("libcrypto.so.0.9.7") self.path("libssl.so.0.9.7") self.path("libexpat.so.1") @@ -487,7 +482,6 @@ class Linux_i686Manifest(LinuxManifest): self.path("libuuid.so", "libuuid.so.1") self.path("libSDL-1.2.so.0") self.path("libELFIO.so") - self.path("libresolv.so", "libresolv.so.2") #self.path("libtcmalloc.so.0") - bugged #self.path("libstacktrace.so.0") - probably bugged self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason diff --git a/indra/test/llmessageconfig_tut.cpp b/indra/test/llmessageconfig_tut.cpp index 1e9f861b25..30a799a1bf 100644 --- a/indra/test/llmessageconfig_tut.cpp +++ b/indra/test/llmessageconfig_tut.cpp @@ -15,6 +15,7 @@ #include "lldir.h" #include "lltimer.h" #include "llframetimer.h" +#include "llsdutil.h" namespace tut { @@ -23,30 +24,30 @@ namespace tut LLMessageConfigTestData() { + LLUUID random; + random.generate(); // generate temp dir - mTestConfigDir = "/tmp/llmessage-config-test"; + std::ostringstream oStr; + oStr << "/tmp/llmessage-config-test-" << random; + mTestConfigDir = oStr.str(); LLFile::mkdir(mTestConfigDir.c_str()); - + writeConfigFile(LLSD()); LLMessageConfig::initClass("simulator", mTestConfigDir); } ~LLMessageConfigTestData() { // rm contents of temp dir - gDirUtilp->deleteFilesInDir(mTestConfigDir, "*"); + int rmfile = LLFile::remove((mTestConfigDir + "/message.xml").c_str()); + ensure_equals("rmfile value", rmfile, 0); // rm temp dir - LLFile::rmdir(mTestConfigDir.c_str()); + int rmdir = LLFile::rmdir(mTestConfigDir.c_str()); + ensure_equals("rmdir value", rmdir, 0); } - void reloadConfig(const LLSD& config) - { - LLMessageConfig::useConfig(config); - } - void writeConfigFile(const LLSD& config) { - std::string configFile = mTestConfigDir + "/message.xml"; - llofstream file(configFile.c_str()); + llofstream file((mTestConfigDir + "/message.xml").c_str()); if (file.is_open()) { LLSDSerialize::toPrettyXML(config, file); @@ -65,7 +66,7 @@ namespace tut { LLSD config; config["serverDefaults"]["simulator"] = "template"; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure server default is not template", LLMessageConfig::getServerDefaultFlavor(), LLMessageConfig::TEMPLATE_FLAVOR); @@ -79,7 +80,7 @@ namespace tut config["serverDefaults"]["simulator"] = "template"; config["messages"]["msg1"]["flavor"] = "template"; config["messages"]["msg2"]["flavor"] = "llsd"; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure msg template flavor", LLMessageConfig::getMessageFlavor("msg1"), LLMessageConfig::TEMPLATE_FLAVOR); @@ -95,7 +96,7 @@ namespace tut LLSD config; config["serverDefaults"]["simulator"] = "llsd"; config["messages"]["msg1"]["trusted-sender"] = true; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure missing message gives no flavor", LLMessageConfig::getMessageFlavor("Test"), LLMessageConfig::NO_FLAVOR); @@ -117,7 +118,7 @@ namespace tut config["messages"]["msg1"]["trusted-sender"] = false; config["messages"]["msg2"]["flavor"] = "llsd"; config["messages"]["msg2"]["trusted-sender"] = true; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure untrusted is untrusted", LLMessageConfig::getSenderTrustedness("msg1"), LLMessageConfig::UNTRUSTED); @@ -136,7 +137,7 @@ namespace tut LLSD config; config["serverDefaults"]["simulator"] = "template"; config["messages"]["msg1"]["flavor"] = "llsd"; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure msg1 exists, has llsd flavor", LLMessageConfig::getMessageFlavor("msg1"), LLMessageConfig::LLSD_FLAVOR); @@ -151,7 +152,7 @@ namespace tut LLSD config; config["capBans"]["MapLayer"] = true; config["capBans"]["MapLayerGod"] = false; - reloadConfig(config); + LLMessageConfig::useConfig(config); ensure_equals("Ensure cap ban true MapLayer", LLMessageConfig::isCapBanned("MapLayer"), true); |