diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 7096ae9c22..a4171729db 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -116,14 +116,14 @@ void LLThread::registerThreadID() // // Handed to the APR thread creation function // -void LLThread::threadRun() +void LLThread::threadRun() { #ifdef LL_WINDOWS - set_thread_name(-1, mName.c_str()); + set_thread_name(-1, mName.c_str()); #endif // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread - mRecorder = new LLTrace::ThreadRecorder( *LLTrace::get_master_thread_recorder() ); + mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); sThreadID = mID; @@ -152,15 +152,13 @@ void LLThread::threadRun() delete mRecorder; - mRecorder = nullptr; + mRecorder = NULL; // We're done with the run function, this thread is done executing now. //NB: we are using this flag to sync across threads...we really need memory barriers here // Todo: add LLMutex per thread instead of flag? // We are using "while (mStatus != STOPPED) {ms_sleep();}" everywhere. mStatus = STOPPED; - - return; } LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : @@ -172,7 +170,6 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : { mID = ++sIDIter; - mRunCondition = new LLCondition(); mDataLock = new LLMutex(); mLocalAPRFilePoolp = NULL ; @@ -235,10 +232,13 @@ void LLThread::shutdown() { // This thread just wouldn't stop, even though we gave it time //LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL; - // Put a stake in its heart. - // ND: There is no such thing as to terminate a std::thread, we detach it so no wait will happen. - // Otherwise craft something platform specific with std::thread::native_handle - mThreadp->detach(); + // Put a stake in its heart. (A very hostile method to force a thread to quit) +#if LL_WINDOWS + TerminateThread(mNativeHandle, 0); +#else + pthread_cancel(mNativeHandle); +#endif + delete mRecorder; mRecorder = NULL; mStatus = STOPPED; @@ -252,7 +252,7 @@ void LLThread::shutdown() delete mDataLock; mDataLock = NULL; - + if (mRecorder) { // missed chance to properly shut down recorder (needs to be done in thread context) @@ -272,14 +272,15 @@ void LLThread::start() try { - mThreadp = new std::thread( std::bind( &LLThread::threadRun, this ) ); - //mThreadp->detach(); + mThreadp = new std::thread(std::bind(&LLThread::threadRun, this)); + mNativeHandle = mThreadp->native_handle(); } - catch( std::system_error& ex ) + catch (std::system_error& ex) { mStatus = STOPPED; LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL; } + } //============================================================================ @@ -354,7 +355,7 @@ U32 LLThread::currentID() // static void LLThread::yield() { - std::this_thread::yield(); + std::this_thread::yield(); } void LLThread::wake() @@ -395,7 +396,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() void LLThreadSafeRefCount::cleanupThreadSafeRefCount() { delete sMutex; - sMutex = nullptr; + sMutex = NULL; } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index fba308ce85..863c9051f3 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -29,11 +29,9 @@ #include "llapp.h" #include "llapr.h" -#include "apr_thread_cond.h" #include "boost/intrusive_ptr.hpp" #include "llmutex.h" #include "llrefcount.h" - #include LL_COMMON_API void assert_main_thread(); @@ -99,15 +97,17 @@ public: private: bool mPaused; + std::thread::native_handle_type mNativeHandle; // for termination in case of issues - void threadRun( ); + // static function passed to APR thread creation routine + void threadRun(); protected: std::string mName; class LLCondition* mRunCondition; LLMutex* mDataLock; - std::thread *mThreadp; + std::thread *mThreadp; EThreadStatus mStatus; U32 mID; LLTrace::ThreadRecorder* mRecorder; diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index d0076f2a9a..37f6bbe97e 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -26,3 +26,4 @@ //#include "linden_common.h" //#include "llthreadsafequeue.h" + diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 8ab1682a38..b0bddac8e5 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -28,10 +28,20 @@ #define LL_LLTHREADSAFEQUEUE_H #include "llexception.h" -#include "llmutex.h" -#include "lltimer.h" -#include #include +#include + +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable:4265) +#endif +// 'std::_Pad' : class has virtual functions, but destructor is not virtual +#include +#include + +#if LL_WINDOWS +#pragma warning (pop) +#endif // // A general queue exception. @@ -62,8 +72,6 @@ public: } }; - - // // Implements a thread safe FIFO. // @@ -104,99 +112,102 @@ public: private: std::deque< ElementT > mStorage; - LLCondition mLock;; - U32 mCapacity; // Really needed? + U32 mCapacity; + + std::mutex mLock; + std::condition_variable mCapacityCond; + std::condition_variable mEmptyCond; }; - - // LLThreadSafeQueue //----------------------------------------------------------------------------- - template -LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity): - mCapacity(capacity) +LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : +mCapacity(capacity) { - ; // No op. } template void LLThreadSafeQueue::pushFront(ElementT const & element) { - while (true) - { - { - LLMutexLock lck(&mLock); - if (mStorage.size() < mCapacity) - { - mStorage.push_front(element); - mLock.signal(); - return; - } - } - ms_sleep(100); - } + while (true) + { + std::unique_lock lock1(mLock); + + if (mStorage.size() < mCapacity) + { + mStorage.push_front(element); + mEmptyCond.notify_one(); + return; + } + + // Storage Full. Wait for signal. + mCapacityCond.wait(lock1); + } } template bool LLThreadSafeQueue::tryPushFront(ElementT const & element) { - LLMutexTrylock lck(&mLock); - if (!lck.isLocked()) - return false; + std::unique_lock lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; - if (mStorage.size() >= mCapacity) - return false; + if (mStorage.size() >= mCapacity) + return false; - mStorage.push_front(element); - mLock.signal(); - return true; + mStorage.push_front(element); + mEmptyCond.notify_one(); + return true; } template ElementT LLThreadSafeQueue::popBack(void) { - while (true) - { - mLock.wait(); - if (!mStorage.empty()) - { - ElementT value = mStorage.back(); - mStorage.pop_back(); - return value; - } - } + while (true) + { + std::unique_lock lock1(mLock); + + if (!mStorage.empty()) + { + ElementT value = mStorage.back(); + mStorage.pop_back(); + mCapacityCond.notify_one(); + return value; + } + + // Storage empty. Wait for signal. + mEmptyCond.wait(lock1); + } } template bool LLThreadSafeQueue::tryPopBack(ElementT & element) { - LLMutexTrylock lck(&mLock); + std::unique_lock lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; - if (!lck.isLocked()) - return false; - if (mStorage.empty()) - return false; + if (mStorage.empty()) + return false; - element = mStorage.back(); - mStorage.pop_back(); - return true; + element = mStorage.back(); + mStorage.pop_back(); + mCapacityCond.notify_one(); + return true; } template size_t LLThreadSafeQueue::size(void) { - // Nicky: apr_queue_size is/was NOT threadsafe. I still play it safe here and rather lock the storage - - LLMutexLock lck(&mLock); - return mStorage.size(); + std::lock_guard lock(mLock); + return mStorage.size(); } - #endif diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 557ae1156a..4c0948a90e 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -565,6 +565,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) // about 700 or so requests and starts issuing TCP RSTs to // new connections. Reuse the DNS lookups for even a few // seconds and no RSTs. + // + // -1 stores forever + // 0 never stores + // any other positive number specifies seconds + // supposedly curl 7.62.0 can use TTL by default, otherwise default is 60 seconds check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout); if (gpolicy.mUseLLProxy) diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index b450f3502e..4ac3f6f991 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -2903,6 +2903,9 @@ void HttpRequestTestObjectType::test<22>() set_test_name("BUG-2295"); +#if LL_WINDOWS && ADDRESS_SIZE == 64 + skip("BUG-2295 - partial load on W64 causes freeze"); +#endif // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2921,6 +2924,7 @@ void HttpRequestTestObjectType::test<22>() // options set options = HttpOptions::ptr_t(new HttpOptions()); options->setRetries(1); // Partial_File is retryable and can timeout in here + options->setDNSCacheTimeout(30); // Get singletons created HttpRequest::createService(); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index aef4084a9f..a18e8938ea 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -29,6 +29,7 @@ #include "llchatitemscontainerctrl.h" #include "lltextbox.h" +#include "llavataractions.h" #include "llavatariconctrl.h" #include "llcommandhandler.h" #include "llfloaterreg.h" @@ -220,6 +221,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) mMsgText = getChild("msg_text", false); mMsgText->setContentTrusted(false); + mMsgText->setIsFriendCallback(LLAvatarActions::isFriend); mMsgText->setText(std::string("")); diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 6ccf62a6ca..a3c67a6750 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -353,7 +353,7 @@ void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_ LLConversationItemParticipant* participant = findParticipant(participant_id); if (participant) { - participant->muteVoice(is_muted); + participant->moderateVoice(is_muted); } } @@ -500,6 +500,7 @@ void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name) LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : LLConversationItem(display_name,uuid,root_view_model), + mIsModeratorMuted(false), mIsModerator(false), mDisplayModeratorLabel(false), mDistToAgent(-1.0) @@ -510,6 +511,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : LLConversationItem(uuid,root_view_model), + mIsModeratorMuted(false), mIsModerator(false), mDisplayModeratorLabel(false), mDistToAgent(-1.0) @@ -599,7 +601,7 @@ void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole) bool LLConversationItemParticipant::isVoiceMuted() { - return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); + return mIsModeratorMuted || LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); } void LLConversationItemParticipant::muteVoice(bool mute_voice) @@ -607,16 +609,16 @@ void LLConversationItemParticipant::muteVoice(bool mute_voice) LLAvatarName av_name; LLAvatarNameCache::get(mUUID, &av_name); LLMuteList * mute_listp = LLMuteList::getInstance(); - bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName()); + bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName(), LLMute::flagVoiceChat); LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT); if (voice_already_muted && !mute_voice) { - mute_listp->remove(mute); + mute_listp->remove(mute, LLMute::flagVoiceChat); } else if (!voice_already_muted && mute_voice) { - mute_listp->add(mute); + mute_listp->add(mute, LLMute::flagVoiceChat); } } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 0cd9e624b2..cbead93dc1 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -197,8 +197,10 @@ public: virtual const std::string& getDisplayName() const { return mDisplayName; } bool isVoiceMuted(); + bool isModeratorMuted() { return mIsModeratorMuted; } bool isModerator() const { return mIsModerator; } void muteVoice(bool mute_voice); + void moderateVoice(bool mute_voice) { mIsModeratorMuted = mute_voice; } void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; } void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; } void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; } @@ -219,6 +221,7 @@ private: void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName void updateName(const LLAvatarName& av_name); + bool mIsModeratorMuted; // default is false bool mIsModerator; // default is false bool mDisplayModeratorLabel; // default is false std::string mDisplayName; diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 240a9d7702..bd37e2cd3f 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -607,6 +607,20 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height) return arranged; } +// virtual +void LLConversationViewParticipant::refresh() +{ + // Refresh the participant view from its model data + LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); + participant_model->resetRefresh(); + + // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat + mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted()); + + // Do the regular upstream refresh + LLFolderViewItem::refresh(); +} + void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder) { // Add the item to the folder (conversation) diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 76da653c26..be32d06808 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -138,6 +138,7 @@ public: virtual ~LLConversationViewParticipant( void ); bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } + /*virtual*/ void refresh(); void addToFolder(LLFolderViewFolder* folder); void addToSession(const LLUUID& session_id); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 268de7eba3..fdb5a6a118 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -436,6 +436,7 @@ BOOL LLPanelLandGeneral::postBuild() mTextSalePending = getChild("SalePending"); mTextOwnerLabel = getChild("Owner:"); mTextOwner = getChild("OwnerText"); + mTextOwner->setIsFriendCallback(LLAvatarActions::isFriend); mContentRating = getChild("ContentRatingText"); mLandType = getChild("LandTypeText"); @@ -1269,6 +1270,7 @@ BOOL LLPanelLandObjects::postBuild() mIconGroup = LLUIImageList::getInstance()->getUIImage("icon_group.tga", 0); mOwnerList = getChild("owner list"); + mOwnerList->setIsFriendCallback(LLAvatarActions::isFriend); mOwnerList->sortByColumnIndex(3, FALSE); childSetCommitCallback("owner list", onCommitList, this); mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9e2f1e6c5c..c965f933b1 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -310,10 +310,10 @@ BOOL LLFloaterModelPreview::postBuild() getChild("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true)); } - childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -487,6 +487,16 @@ void LLFloaterModelPreview::initModelPreview() mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1)); } +void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl) +{ + if (mModelPreview) + { + auto name = ctrl->getName(); + mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name]; + } + toggleCalculateButton(true); +} + void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl) { if (mModelPreview) @@ -686,6 +696,7 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda void LLFloaterModelPreview::toggleGenarateNormals() { bool enabled = childGetValue("gen_normals").asBoolean(); + mModelPreview->mViewOption["gen_normals"] = enabled; childSetEnabled("crease_angle", enabled); if(enabled) { mModelPreview->generateNormals(); @@ -1255,10 +1266,8 @@ void LLFloaterModelPreview::initDecompControls() std::string label = llformat("%.1f", value); combo_box->add(label, value, ADD_BOTTOM, true); } - combo_box->setValue(param[i].mDefault.mFloat); - } - + combo_box->setValue(param[i].mDefault.mFloat); combo_box->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); } } @@ -1330,7 +1339,7 @@ void LLFloaterModelPreview::initDecompControls() //LL_INFOS() << "-----------------------------" << LL_ENDL; } } - + mDefaultDecompParams = mDecompParams; childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this); } @@ -4768,6 +4777,7 @@ void LLFloaterModelPreview::onReset(void* user_data) std::string filename = mp->mLODFile[LLModel::LOD_HIGH]; fmp->resetDisplayOptions(); + fmp->resetUploadOptions(); //reset model preview fmp->initModelPreview(); @@ -4881,11 +4891,6 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg) mStatusMessage = msg; } -void LLFloaterModelPreview::toggleCalculateButton() -{ - toggleCalculateButton(true); -} - void LLFloaterModelPreview::toggleCalculateButton(bool visible) { mCalculateBtn->setVisible(visible); @@ -4947,6 +4952,37 @@ void LLFloaterModelPreview::resetDisplayOptions() } } +void LLFloaterModelPreview::resetUploadOptions() +{ + childSetValue("import_scale", 1); + childSetValue("pelvis_offset", 0); + childSetValue("physics_explode", 0); + childSetValue("physics_file", ""); + childSetVisible("Retain%", false); + childSetVisible("Retain%_label", false); + childSetVisible("Detail Scale", true); + childSetVisible("Detail Scale label", true); + + getChild("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE); + for (S32 lod = 0; lod < NUM_LOD - 1; ++lod) + { + getChild("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE); + childSetValue("lod_file_" + lod_name[lod], ""); + } + + getChild("physics_lod_combo")->setCurrentByIndex(0); + + for(auto& p : mDefaultDecompParams) + { + std::string ctrl_name(p.first); + LLUICtrl* ctrl = getChild(ctrl_name); + if (ctrl) + { + ctrl->setValue(p.second); + } + } +} + void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) { mModelPhysicsFee = result; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 4e9b575882..1677fe0571 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -109,6 +109,7 @@ public: void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false); void onViewOptionChecked(LLUICtrl* ctrl); + void onUploadOptionChecked(LLUICtrl* ctrl); bool isViewOptionChecked(const LLSD& userdata); bool isViewOptionEnabled(const LLSD& userdata); void setViewOptionEnabled(const std::string& option, bool enabled); @@ -179,6 +180,7 @@ protected: LLModelPreview* mModelPreview; LLPhysicsDecomp::decomp_params mDecompParams; + LLPhysicsDecomp::decomp_params mDefaultDecompParams; S32 mLastMouseX; S32 mLastMouseY; @@ -203,7 +205,6 @@ protected: private: void onClickCalculateBtn(); - void toggleCalculateButton(); void onLoDSourceCommit(S32 lod); @@ -213,6 +214,8 @@ private: // resets display options of model preview to their defaults. void resetDisplayOptions(); + void resetUploadOptions(); + void createSmoothComboBox(LLComboBox* combo_box, float min, float max); LLButton* mUploadBtn; diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index ef8ad056d9..e773c407d3 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -83,8 +83,6 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this)); mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this)); mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this)); - mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this)); - mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this)); mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); @@ -159,6 +157,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { U32 request_flags; U32 total_count; + U64 total_memory = 0; msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags); msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count); @@ -206,6 +205,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { parcel_buf = parcel_name; script_memory = script_size; + total_memory += script_size; } } @@ -279,8 +279,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { setTitle(getString("top_scripts_title")); list->setColumnLabel("score", getString("scripts_score_label")); - + LLUIString format = getString("top_scripts_text"); + total_memory /= 1024; + format.setArg("[MEMORY]", llformat("%ld", total_memory)); format.setArg("[COUNT]", llformat("%d", total_count)); format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild("title_text")->setValue(LLSD(format)); @@ -364,7 +366,7 @@ void LLFloaterTopObjects::onClickShowBeacon() showBeacon(); } -void LLFloaterTopObjects::doToObjects(int action, bool all) +void LLFloaterTopObjects::returnObjects(bool all) { LLMessageSystem *msg = gMessageSystem; @@ -388,14 +390,7 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) } if (start_message) { - if (action == ACTION_RETURN) - { - msg->newMessageFast(_PREHASH_ParcelReturnObjects); - } - else - { - msg->newMessageFast(_PREHASH_ParcelDisableObjects); - } + msg->newMessageFast(_PREHASH_ParcelReturnObjects); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); @@ -429,7 +424,7 @@ bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD if(!instance) return false; if (option == 0) { - instance->doToObjects(ACTION_RETURN, true); + instance->returnObjects(true); } return false; } @@ -442,31 +437,7 @@ void LLFloaterTopObjects::onReturnAll() void LLFloaterTopObjects::onReturnSelected() { - doToObjects(ACTION_RETURN, false); -} - - -//static -bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); - if(!instance) return false; - if (option == 0) - { - instance->doToObjects(ACTION_DISABLE, true); - } - return false; -} - -void LLFloaterTopObjects::onDisableAll() -{ - LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll); -} - -void LLFloaterTopObjects::onDisableSelected() -{ - doToObjects(ACTION_DISABLE, false); + returnObjects(false); } diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 6b17295bcd..495ff41eff 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -79,12 +79,10 @@ private: static void onDoubleClickObjectsList(void* data); void onClickShowBeacon(); - void doToObjects(int action, bool all); + void returnObjects(bool all); void onReturnAll(); void onReturnSelected(); - void onDisableAll(); - void onDisableSelected(); // TP to object void onTeleportToObject(); @@ -99,7 +97,6 @@ private: void onAvatarCheck(const LLUUID& avatar_id, const LLAvatarName av_name); static bool callbackReturnAll(const LLSD& notification, const LLSD& response); - static bool callbackDisableAll(const LLSD& notification, const LLSD& response); void onGetByOwnerName(); void onGetByObjectName(); @@ -121,12 +118,6 @@ private: F32 mtotalScore; - enum - { - ACTION_RETURN = 0, - ACTION_DISABLE - }; - static LLFloaterTopObjects* sInstance; }; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 36a1932835..c48bb1715f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1572,7 +1572,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, break; default: - LL_INFOS() << "Unhandled asset type (llassetstorage.h): " + LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL; break; } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 75801e21d1..e79c0e8678 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1975,9 +1975,19 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) if (LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) { - LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() - << " type: " << item->getType() - << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + if (item->getType() >= LLAssetType::AT_COUNT) + { + // Not yet supported. + LL_DEBUGS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() + << " type: " << item->getType() + << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + } + else + { + LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() + << " type: " << item->getType() + << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + } } // This condition means that we tried to add a link without the baseobj being in memory. diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 4c404f65b0..6b8f77d7b0 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -943,7 +943,8 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) if (objectp->getType() >= LLAssetType::AT_COUNT) { - LL_WARNS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : " + // Example: Happens when we add assets of new, not yet supported type to library + LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : " << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() << LL_ENDL; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index dd47c0bcc7..7ebaa856f1 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -660,43 +660,10 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vectoradd(dirname, filename); - - LLFILE * filep = LLFile::fopen(fullname, "rb"); - if (NULL != filep) + if (isTranscriptFileFound(fullname)) { - if(makeLogFileName("chat")== fullname) - { - //Add Nearby chat history to the list of transcriptions - list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); - LLFile::close(filep); - continue; - } - char buffer[LOG_RECALL_SIZE]; - - fseek(filep, 0, SEEK_END); // seek to end of file - S32 bytes_to_read = ftell(filep); // get current file pointer - fseek(filep, 0, SEEK_SET); // seek back to beginning of file - - // limit the number characters to read from file - if (bytes_to_read >= LOG_RECALL_SIZE) - { - bytes_to_read = LOG_RECALL_SIZE - 1; - } - - if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep)) - { - //matching a timestamp - boost::match_results matches; - // Seconds in timestamp - //if (boost::regex_match(std::string(buffer), matches, TIMESTAMP)) - if (boost::regex_match(std::string(buffer), matches, TIMESTAMP) || boost::regex_match(std::string(buffer), matches, TIMESTAMP_AND_SEC)) - // - { - list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); - } - } - LLFile::close(filep); - } + list_of_transcriptions.push_back(fullname); + } } } @@ -849,57 +816,13 @@ void LLLogChat::deleteTranscripts() // static bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) { - // FIRE-13725 / CHUIBUG-222: Viewer freezes when opening preferences or right-clicking on friends' names - //std::vector list_of_transcriptions; - //LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); - - //if (list_of_transcriptions.size() > 0) - //{ - // LLAvatarName avatar_name; - // LLAvatarNameCache::get(avatar_id, &avatar_name); - // // [Legacy IM logfile names] - // //std::string avatar_user_name = avatar_name.getAccountName(); - // std::string avatar_user_name; - // if (gSavedSettings.getBOOL("UseLegacyIMLogNames")) - // { - // avatar_user_name = avatar_name.getUserName(); - // avatar_user_name = avatar_user_name.substr(0, avatar_user_name.find(" Resident"));; - // } - // else - // { - // avatar_user_name = avatar_name.getAccountName(); - // std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - // } - // // [Legacy IM logfile names] - // if(!is_group) - // { - // //std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - // BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - // { - // if (std::string::npos != transcript_file_name.find(avatar_user_name)) - // { - // return true; - // } - // } - // } - // else - // { - // std::string file_name; - // gCacheName->getGroupName(avatar_id, file_name); - // file_name = makeLogFileName(file_name); - // BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - // { - // if (transcript_file_name == file_name) - // { - // return true; - // } - // } - // } - - //} - std::string file_name; - if (!is_group) + //LLAvatarName avatar_name; + //LLAvatarNameCache::get(avatar_id, &avatar_name); + //std::string avatar_user_name = avatar_name.getAccountName(); + if(!is_group) { + // [Legacy IM logfile names] + //std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); LLAvatarName avatar_name; LLAvatarNameCache::get(avatar_id, &avatar_name); std::string avatar_user_name; @@ -913,60 +836,68 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) avatar_user_name = avatar_name.getAccountName(); std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); } - file_name = makeLogFileName(avatar_user_name); + // [Legacy IM logfile names] + return isTranscriptFileFound(makeLogFileName(avatar_user_name)); } else { + std::string file_name; gCacheName->getGroupName(avatar_id, file_name); file_name = makeLogFileName(file_name); + return isTranscriptFileFound(makeLogFileName(file_name)); } - if ( (!file_name.empty()) && (LLFile::isfile(file_name)) ) - { - return true; - } - // - return false; } bool LLLogChat::isNearbyTranscriptExist() { - // FIRE-13725 / CHUIBUG-222: Viewer freezes when opening preferences or right-clicking on friends' names - //std::vector list_of_transcriptions; - //LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); - - //std::string file_name; - //file_name = makeLogFileName("chat"); - //BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - //{ - // if (transcript_file_name == file_name) - // { - // return true; - // } - //} - std::string strFilePath = makeLogFileName("chat"); - if ( (!strFilePath.empty()) && (LLFile::isfile(strFilePath)) ) - { - return true; - } - // - return false; + return isTranscriptFileFound(makeLogFileName("chat"));; } bool LLLogChat::isAdHocTranscriptExist(std::string file_name) { - std::vector list_of_transcriptions; - LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); + return isTranscriptFileFound(makeLogFileName(file_name));; +} - file_name = makeLogFileName(file_name); - BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) +// static +bool LLLogChat::isTranscriptFileFound(std::string fullname) +{ + bool result = false; + LLFILE * filep = LLFile::fopen(fullname, "rb"); + if (NULL != filep) { - if (transcript_file_name == file_name) - { - return true; + if (makeLogFileName("chat") == fullname) + { + LLFile::close(filep); + return true; } + char buffer[LOG_RECALL_SIZE]; + + fseek(filep, 0, SEEK_END); // seek to end of file + S32 bytes_to_read = ftell(filep); // get current file pointer + fseek(filep, 0, SEEK_SET); // seek back to beginning of file + + // limit the number characters to read from file + if (bytes_to_read >= LOG_RECALL_SIZE) + { + bytes_to_read = LOG_RECALL_SIZE - 1; + } + + if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep)) + { + //matching a timestamp + boost::match_results matches; + // Seconds in timestamp + //if (boost::regex_match(std::string(buffer), matches, TIMESTAMP)) + if (boost::regex_match(std::string(buffer), matches, TIMESTAMP) || boost::regex_match(std::string(buffer), matches, TIMESTAMP_AND_SEC)) + // + { + result = true; + } + } + LLFile::close(filep); } - return false; + return result; } //*TODO mark object's names in a special way so that they will be distinguishable form avatar name diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 6022e539a9..fcbd38a044 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -121,6 +121,7 @@ public: static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false); static bool isNearbyTranscriptExist(); static bool isAdHocTranscriptExist(std::string file_name); + static bool isTranscriptFileFound(std::string fullname); static bool historyThreadsFinished(LLUUID session_id); static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 947666a89b..1fdf1db512 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -63,6 +63,9 @@ #include const S32 LOGIN_MAX_RETRIES = 3; +const F32 LOGIN_SRV_TIMEOUT_MIN = 10; +const F32 LOGIN_SRV_TIMEOUT_MAX = 120; +const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time class LLLoginInstance::Disposable { public: @@ -247,8 +250,10 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // Specify desired timeout/retry options LLSD http_params; - http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout"); + F32 srv_timeout = llclamp(gSavedSettings.getF32("LoginSRVTimeout"), LOGIN_SRV_TIMEOUT_MIN, LOGIN_SRV_TIMEOUT_MAX); + http_params["timeout"] = srv_timeout; http_params["retries"] = LOGIN_MAX_RETRIES; + http_params["DNSCacheTimeout"] = srv_timeout * LOGIN_DNS_TIMEOUT_FACTOR; //Default: indefinite mRequestData.clear(); mRequestData["method"] = "login_to_simulator"; diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index 79bab4b077..6736e9a950 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void) { if(mQueue != 0) return; - mQueue = new LLThreadSafeQueue( 1024); + mQueue = new LLThreadSafeQueue(1024); mMainLoopConnection = LLEventPumps::instance(). obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 492daea14d..c8235e08a5 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -74,6 +74,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) mImageLevel3(p.image_level_3), mAutoUpdate(p.auto_update), mSpeakerId(p.speaker_id), + mIsModeratorMuted(false), mIsAgentControl(false), mIndicatorToggled(false), mShowParticipantsSpeaking(false) @@ -128,7 +129,7 @@ void LLOutputMonitorCtrl::draw() //const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // Centralized voice power level - if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull()) + if (getVisible() && mAutoUpdate && !getIsMuted() && mSpeakerId.notNull()) { setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId)); if(mIsAgentControl) @@ -161,7 +162,7 @@ void LLOutputMonitorCtrl::draw() LLPointer icon; // Centralized voice power level - //if (mIsMuted) + //if (getIsMuted()) //{ // icon = mImageMute; //} diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index fdc4224772..1db2e670f6 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -72,9 +72,11 @@ public: void setPower(F32 val); F32 getPower(F32 val) const { return mPower; } - + + bool getIsMuted() const { return (mIsMuted || mIsModeratorMuted); } + void setIsModeratorMuted(bool val) { mIsModeratorMuted = val; } + // FS Communications UI - bool getIsMuted() const { return mIsMuted; } void setIsMuted(bool val) { mIsMuted = val; } // @@ -136,6 +138,7 @@ private: F32 mPower; bool mIsAgentControl; + bool mIsModeratorMuted; bool mIsMuted; bool mIsTalking; bool mShowParticipantsSpeaking; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 44a8e8382b..39b73fe1c4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6966,17 +6966,6 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp void script_question_mute(const LLUUID& item_id, const std::string& object_name); -bool unknown_script_question_cb(const LLSD& notification, const LLSD& response) -{ - // Only care if they muted the object here. - if ( response["Mute"] ) // mute - { - LLUUID task_id = notification["payload"]["task_id"].asUUID(); - script_question_mute(task_id,notification["payload"]["object_name"].asString()); - } - return false; -} - void experiencePermissionBlock(LLUUID experience, LLSD result) { LLSD permission; @@ -7092,8 +7081,7 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name) bool matches(const LLNotificationPtr notification) const { if (notification->getName() == "ScriptQuestionCaution" - || notification->getName() == "ScriptQuestion" - || notification->getName() == "UnknownScriptQuestion") + || notification->getName() == "ScriptQuestion") { return (notification->getPayload()["task_id"].asUUID() == blocked_id); } @@ -7110,7 +7098,6 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name) static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb); static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb); static LLNotificationFunctorRegistration script_question_cb_reg_3("ScriptQuestionExperience", script_question_cb); -static LLNotificationFunctorRegistration unknown_script_question_cb_reg("UnknownScriptQuestion", unknown_script_question_cb); void process_script_experience_details(const LLSD& experience_details, LLSD args, LLSD payload) { @@ -7232,14 +7219,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data) args["QUESTIONS"] = script_question; if (known_questions != questions) - { // This is in addition to the normal dialog. - LLSD payload; - payload["task_id"] = taskid; - payload["item_id"] = itemid; - payload["object_name"] = object_name; - - args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL"); - LLNotificationsUtil::add("UnknownScriptQuestion",args,payload); + { + // This is in addition to the normal dialog. + // Viewer got a request for not supported/implemented permission + LL_WARNS("Messaging") << "Object \"" << object_name << "\" requested " << script_question + << " permission. Permission is unknown and can't be granted. Item id: " << itemid + << " taskid:" << taskid << LL_ENDL; make_ui_sound("UISndScriptFloaterOpen"); // FIRE-16958: Incoming script permission request doesn't trigger a sound } diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 7cc3706d08..e18b42d025 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -362,6 +362,10 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const { httpOpts->setRetries(httpParams["retries"].asInteger()); } + if (httpParams.has("DNSCacheTimeout")) + { + httpOpts->setDNSCacheTimeout(httpParams["DNSCacheTimeout"].asInteger()); + } bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert"); mCertStore = gSavedSettings.getString("CertStore"); diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml index a8d6e5fb63..f5a88e8cd3 100644 --- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml @@ -213,6 +213,7 @@ layout="topleft" top_pad="0" name="share_with_group" + tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions." width="92" /> @@ -276,7 +280,7 @@ label="Transfer" layout="topleft" name="next_owner_transfer" - tool_tip="Next owner can give away or resell this object" + tool_tip="Next owner can give away or resell this object." width="92" /> diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index 6b5866fce9..899383085c 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -2,7 +2,7 @@ - [COUNT] scripts taking a total of [TIME] ms + [COUNT] scripts taking a total of [TIME] ms and using [MEMORY] KB @@ -298,30 +298,6 @@ - -