diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp index e0590dfdff..a42ecefd23 100644 --- a/indra/llmessage/llxfer.cpp +++ b/indra/llmessage/llxfer.cpp @@ -99,7 +99,22 @@ void LLXfer::cleanup () S32 LLXfer::startSend (U64 xfer_id, const LLHost &remote_host) { - LL_WARNS() << "undifferentiated LLXfer::startSend for " << getFileName() << LL_ENDL; + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::startSend for " << getFileName() << LL_ENDL; + return (-1); +} + +/////////////////////////////////////////////////////////// + +void LLXfer::closeFileHandle() +{ + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::closeFileHandle for " << getFileName() << LL_ENDL; +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer::reopenFileHandle() +{ + LL_WARNS("Xfer") << "unexpected call to base class LLXfer::reopenFileHandle for " << getFileName() << LL_ENDL; return (-1); } @@ -127,14 +142,14 @@ S32 LLXfer::receiveData (char *datap, S32 data_size) S32 retval = 0; if (((S32) mBufferLength + data_size) > getMaxBufferSize()) - { + { // Write existing data to disk if it's larger than the buffer size retval = flush(); } if (!retval) { if (datap != NULL) - { + { // Append new data to mBuffer memcpy(&mBuffer[mBufferLength],datap,data_size); /*Flawfinder: ignore*/ mBufferLength += data_size; } @@ -248,7 +263,12 @@ void LLXfer::sendPacket(S32 packet_num) gMessageSystem->nextBlockFast(_PREHASH_DataPacket); gMessageSystem->addBinaryDataFast(_PREHASH_Data, &fdata_buf,fdata_size); - gMessageSystem->sendMessage(mRemoteHost); + S32 sent_something = gMessageSystem->sendMessage(mRemoteHost); + if (sent_something == 0) + { + abort(LL_ERR_CIRCUIT_GONE); + return; + } ACKTimer.reset(); mWaitingForACK = TRUE; @@ -326,12 +346,15 @@ void LLXfer::abort (S32 result_code) LL_INFOS() << "Aborting xfer from " << mRemoteHost << " named " << getFileName() << " - error: " << result_code << LL_ENDL; - gMessageSystem->newMessageFast(_PREHASH_AbortXfer); - gMessageSystem->nextBlockFast(_PREHASH_XferID); - gMessageSystem->addU64Fast(_PREHASH_ID, mID); - gMessageSystem->addS32Fast(_PREHASH_Result, result_code); - - gMessageSystem->sendMessage(mRemoteHost); + if (result_code != LL_ERR_CIRCUIT_GONE) + { + gMessageSystem->newMessageFast(_PREHASH_AbortXfer); + gMessageSystem->nextBlockFast(_PREHASH_XferID); + gMessageSystem->addU64Fast(_PREHASH_ID, mID); + gMessageSystem->addS32Fast(_PREHASH_Result, result_code); + + gMessageSystem->sendMessage(mRemoteHost); + } mStatus = e_LL_XFER_ABORTED; } diff --git a/indra/llmessage/llxfer.h b/indra/llmessage/llxfer.h index edf5eeb82d..3be8da4fbe 100644 --- a/indra/llmessage/llxfer.h +++ b/indra/llmessage/llxfer.h @@ -62,7 +62,7 @@ class LLXfer S32 mXferSize; char *mBuffer; - U32 mBufferLength; + U32 mBufferLength; // Size of valid data, not actual allocated buffer size U32 mBufferStartOffset; BOOL mBufferContainsEOF; @@ -90,7 +90,9 @@ class LLXfer void init(S32 chunk_size); virtual void cleanup(); - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual void sendPacket(S32 packet_num); virtual void sendNextPacket(); virtual void resendLastPacket(); diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp index 8e2ed890e7..ad55e389f3 100644 --- a/indra/llmessage/llxfer_file.cpp +++ b/indra/llmessage/llxfer_file.cpp @@ -206,7 +206,8 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) mBufferLength = 0; mBufferStartOffset = 0; - + + // We leave the file open, assuming we'll start reading and sending soon mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ if (mFp) { @@ -232,6 +233,36 @@ S32 LLXfer_File::startSend (U64 xfer_id, const LLHost &remote_host) return (retval); } +/////////////////////////////////////////////////////////// +void LLXfer_File::closeFileHandle() +{ + if (mFp) + { + fclose(mFp); + mFp = NULL; + } +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer_File::reopenFileHandle() +{ + S32 retval = LL_ERR_NOERR; // presume success + + if (mFp == NULL) + { + mFp = LLFile::fopen(mLocalFilename,"rb"); /* Flawfinder : ignore */ + if (mFp == NULL) + { + LL_INFOS("Xfer") << "Warning: " << mLocalFilename << " not found when re-opening file" << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; +} + + /////////////////////////////////////////////////////////// S32 LLXfer_File::getMaxBufferSize () @@ -285,9 +316,12 @@ S32 LLXfer_File::flush() if (mFp) { - if (fwrite(mBuffer,1,mBufferLength,mFp) != mBufferLength) + S32 write_size = fwrite(mBuffer,1,mBufferLength,mFp); + if (write_size != mBufferLength) { - LL_WARNS() << "Short write" << LL_ENDL; + LL_WARNS("Xfer") << "Non-matching write size, requested " << mBufferLength + << " but wrote " << write_size + << LL_ENDL; } // LL_INFOS() << "******* wrote " << mBufferLength << " bytes of file xfer" << LL_ENDL; diff --git a/indra/llmessage/llxfer_file.h b/indra/llmessage/llxfer_file.h index a37dda6732..ab9374549e 100644 --- a/indra/llmessage/llxfer_file.h +++ b/indra/llmessage/llxfer_file.h @@ -61,8 +61,10 @@ class LLXfer_File : public LLXfer virtual S32 startDownload(); virtual S32 processEOF(); - - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual S32 suck(S32 start_position); virtual S32 flush(); diff --git a/indra/llmessage/llxfer_mem.cpp b/indra/llmessage/llxfer_mem.cpp index 3bea08f2e5..78a3e4f558 100644 --- a/indra/llmessage/llxfer_mem.cpp +++ b/indra/llmessage/llxfer_mem.cpp @@ -80,28 +80,6 @@ void LLXfer_Mem::setXferSize (S32 xfer_size) /////////////////////////////////////////////////////////// -U64 LLXfer_Mem::registerXfer(U64 xfer_id, const void *datap, const S32 length) -{ - mID = xfer_id; - - if (datap) - { - setXferSize(length); - if (mBuffer) - { - memcpy(mBuffer,datap,length); /* Flawfinder : ignore */ - mBufferLength = length; - } - else - { - xfer_id = 0; - } - } - - mStatus = e_LL_XFER_REGISTERED; - return (xfer_id); -} - S32 LLXfer_Mem::startSend (U64 xfer_id, const LLHost &remote_host) { S32 retval = LL_ERR_NOERR; // presume success diff --git a/indra/llmessage/llxfer_mem.h b/indra/llmessage/llxfer_mem.h index b5adf837df..d07779de87 100644 --- a/indra/llmessage/llxfer_mem.h +++ b/indra/llmessage/llxfer_mem.h @@ -53,7 +53,6 @@ class LLXfer_Mem : public LLXfer virtual void cleanup(); virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); - virtual U64 registerXfer(U64 xfer_id, const void *datap, const S32 length); virtual void setXferSize (S32 data_size); virtual S32 initializeRequest(U64 xfer_id, diff --git a/indra/llmessage/llxfer_vfile.cpp b/indra/llmessage/llxfer_vfile.cpp index 4a378d1d34..5d41180192 100644 --- a/indra/llmessage/llxfer_vfile.cpp +++ b/indra/llmessage/llxfer_vfile.cpp @@ -205,6 +205,38 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host) } /////////////////////////////////////////////////////////// + +void LLXfer_VFile::closeFileHandle() +{ + if (mVFile) + { + delete mVFile; + mVFile = NULL; + } +} + +/////////////////////////////////////////////////////////// + +S32 LLXfer_VFile::reopenFileHandle() +{ + S32 retval = LL_ERR_NOERR; // presume success + + if (mVFile == NULL) + { + mVFile =new LLVFile(mVFS, mLocalID, mType, LLVFile::READ); + if (mVFile == NULL) + { + LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL; + retval = LL_ERR_FILE_NOT_FOUND; + } + } + + return retval; +} + + +/////////////////////////////////////////////////////////// + void LLXfer_VFile::setXferSize (S32 xfer_size) { LLXfer::setXferSize(xfer_size); diff --git a/indra/llmessage/llxfer_vfile.h b/indra/llmessage/llxfer_vfile.h index 048bf49dcc..b606c08122 100644 --- a/indra/llmessage/llxfer_vfile.h +++ b/indra/llmessage/llxfer_vfile.h @@ -66,8 +66,10 @@ class LLXfer_VFile : public LLXfer virtual S32 startDownload(); virtual S32 processEOF(); - - virtual S32 startSend (U64 xfer_id, const LLHost &remote_host); + + virtual S32 startSend(U64 xfer_id, const LLHost &remote_host); + virtual void closeFileHandle(); + virtual S32 reopenFileHandle(); virtual S32 suck(S32 start_position); virtual S32 flush(); diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 2ceb64ce8f..38ba4b1624 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -44,6 +44,8 @@ const S32 LL_PACKET_RETRY_LIMIT = 10; // packet retransmission limit const S32 LL_DEFAULT_MAX_SIMULTANEOUS_XFERS = 10; const S32 LL_DEFAULT_MAX_REQUEST_FIFO_XFERS = 1000; +const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500; + #define LL_XFER_PROGRESS_MESSAGES 0 #define LL_XFER_TEST_REXMIT 0 @@ -66,10 +68,10 @@ LLXferManager::~LLXferManager () void LLXferManager::init (LLVFS *vfs) { - mSendList = NULL; - mReceiveList = NULL; + cleanup(); setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS); + setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS); setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS); mVFS = vfs; @@ -83,29 +85,14 @@ void LLXferManager::init (LLVFS *vfs) void LLXferManager::cleanup () { - LLXfer *xferp; - LLXfer *delp; - for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); mOutgoingHosts.clear(); - delp = mSendList; - while (delp) - { - xferp = delp->mNext; - delete delp; - delp = xferp; - } - mSendList = NULL; + for_each(mSendList.begin(), mSendList.end(), DeletePointer()); + mSendList.clear(); - delp = mReceiveList; - while (delp) - { - xferp = delp->mNext; - delete delp; - delp = xferp; - } - mReceiveList = NULL; + for_each(mReceiveList.begin(), mReceiveList.end(), DeletePointer()); + mReceiveList.clear(); } /////////////////////////////////////////////////////////// @@ -122,6 +109,11 @@ void LLXferManager::setMaxOutgoingXfersPerCircuit(S32 max_num) mMaxOutgoingXfersPerCircuit = max_num; } +void LLXferManager::setHardLimitOutgoingXfersPerCircuit(S32 max_num) +{ + mHardLimitOutgoingXfersPerCircuit = max_num; +} + void LLXferManager::setUseAckThrottling(const BOOL use) { mUseAckThrottling = use; @@ -148,20 +140,19 @@ void LLXferManager::setAckThrottleBPS(const F32 bps) void LLXferManager::updateHostStatus() { - LLXfer *xferp; - LLHostStatus *host_statusp = NULL; - for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); mOutgoingHosts.clear(); - for (xferp = mSendList; xferp; xferp = xferp->mNext) + for (xfer_list_t::iterator send_iter = mSendList.begin(); + send_iter != mSendList.end(); ++send_iter) { + LLHostStatus *host_statusp = NULL; for (status_list_t::iterator iter = mOutgoingHosts.begin(); iter != mOutgoingHosts.end(); ++iter) { - host_statusp = *iter; - if (host_statusp->mHost == xferp->mRemoteHost) + if ((*iter)->mHost == (*send_iter)->mRemoteHost) { + host_statusp = *iter; break; } } @@ -170,23 +161,22 @@ void LLXferManager::updateHostStatus() host_statusp = new LLHostStatus(); if (host_statusp) { - host_statusp->mHost = xferp->mRemoteHost; + host_statusp->mHost = (*send_iter)->mRemoteHost; mOutgoingHosts.push_front(host_statusp); } } if (host_statusp) { - if (xferp->mStatus == e_LL_XFER_PENDING) + if ((*send_iter)->mStatus == e_LL_XFER_PENDING) { host_statusp->mNumPending++; } - else if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) + else if ((*send_iter)->mStatus == e_LL_XFER_IN_PROGRESS) { host_statusp->mNumActive++; } } - - } + } } /////////////////////////////////////////////////////////// @@ -209,14 +199,15 @@ void LLXferManager::printHostStatus() /////////////////////////////////////////////////////////// -LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head) +LLXfer *LLXferManager::findXfer(U64 id, xfer_list_t & xfer_list) { - LLXfer *xferp; - for (xferp = list_head; xferp; xferp = xferp->mNext) + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) { - if (xferp->mID == id) + if ((*iter)->mID == id) { - return(xferp); + return(*iter); } } return(NULL); @@ -225,29 +216,34 @@ LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head) /////////////////////////////////////////////////////////// -void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head) +void LLXferManager::removeXfer(LLXfer *delp, xfer_list_t & xfer_list) { - // This function assumes that delp will only occur in the list - // zero or one times. if (delp) - { - if (*list_head == delp) + { + std::string direction = "send"; + if (&xfer_list == &mReceiveList) { - *list_head = delp->mNext; - delete (delp); + std::string direction = "receive"; + xfer_list = mSendList; } - else + + // This assumes that delp will occur in the list once at most + // Find the pointer in the list + for (xfer_list_t::iterator iter = xfer_list.begin(); + iter != xfer_list.end(); + ++iter) { - LLXfer *xferp = *list_head; - while (xferp->mNext) + if ((*iter) == delp) { - if (xferp->mNext == delp) - { - xferp->mNext = delp->mNext; - delete (delp); - break; - } - xferp = xferp->mNext; + LL_DEBUGS("Xfer") << "Deleting xfer to host " << (*iter)->mRemoteHost + << " of " << (*iter)->mXferSize << " bytes" + << ", status " << (S32)((*iter)->mStatus) + << " from the " << direction << " list" + << LL_ENDL; + + xfer_list.erase(iter); + delete (delp); + break; } } } @@ -272,7 +268,7 @@ U32 LLXferManager::numActiveListEntries(LLXfer *list_head) /////////////////////////////////////////////////////////// -S32 LLXferManager::numPendingXfers(const LLHost &host) +LLHostStatus * LLXferManager::findHostStatus(const LLHost &host) { LLHostStatus *host_statusp = NULL; @@ -282,26 +278,32 @@ S32 LLXferManager::numPendingXfers(const LLHost &host) host_statusp = *iter; if (host_statusp->mHost == host) { - return (host_statusp->mNumPending); + return (host_statusp); } } return 0; } +/////////////////////////////////////////////////////////// + +S32 LLXferManager::numPendingXfers(const LLHost &host) +{ + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + return host_statusp->mNumPending; + } + return 0; +} + /////////////////////////////////////////////////////////// S32 LLXferManager::numActiveXfers(const LLHost &host) { - LLHostStatus *host_statusp = NULL; - - for (status_list_t::iterator iter = mOutgoingHosts.begin(); - iter != mOutgoingHosts.end(); ++iter) + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) { - host_statusp = *iter; - if (host_statusp->mHost == host) - { - return (host_statusp->mNumActive); - } + return host_statusp->mNumActive; } return 0; } @@ -372,35 +374,6 @@ BOOL LLXferManager::isLastPacket(S32 packet_num) /////////////////////////////////////////////////////////// -U64 LLXferManager::registerXfer(const void *datap, const S32 length) -{ - LLXfer *xferp; - U64 xfer_id = getNextID(); - - xferp = (LLXfer *) new LLXfer_Mem(); - if (xferp) - { - xferp->mNext = mSendList; - mSendList = xferp; - - xfer_id = ((LLXfer_Mem *)xferp)->registerXfer(xfer_id, datap,length); - - if (!xfer_id) - { - removeXfer(xferp,&mSendList); - } - } - else - { - LL_ERRS() << "Xfer allocation error" << LL_ENDL; - xfer_id = 0; - } - - return(xfer_id); -} - -/////////////////////////////////////////////////////////// - U64 LLXferManager::requestFile(const std::string& local_filename, const std::string& remote_filename, ELLPath remote_path, @@ -411,30 +384,33 @@ U64 LLXferManager::requestFile(const std::string& local_filename, BOOL is_priority, BOOL use_big_packets) { - LLXfer *xferp; + LLXfer_File* file_xfer_p = NULL; - for (xferp = mReceiveList; xferp ; xferp = xferp->mNext) + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) { - if (xferp->getXferTypeTag() == LLXfer::XFER_FILE - && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename)) - && (((LLXfer_File*)xferp)->matchesRemoteFilename(remote_filename, remote_path)) - && (remote_host == xferp->mRemoteHost) - && (callback == xferp->mCallback) - && (user_data == xferp->mCallbackDataHandle)) - + if ((*iter)->getXferTypeTag() == LLXfer::XFER_FILE) { - // cout << "requested a xfer already in progress" << endl; - return xferp->mID; + file_xfer_p = (LLXfer_File*)(*iter); + if (file_xfer_p->matchesLocalFilename(local_filename) + && file_xfer_p->matchesRemoteFilename(remote_filename, remote_path) + && (remote_host == file_xfer_p->mRemoteHost) + && (callback == file_xfer_p->mCallback) + && (user_data == file_xfer_p->mCallbackDataHandle)) + { + // Already have the request (already in progress) + return (*iter)->mID; + } } } U64 xfer_id = 0; S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1; - xferp = (LLXfer *) new LLXfer_File(chunk_size); - if (xferp) + file_xfer_p = new LLXfer_File(chunk_size); + if (file_xfer_p) { - addToList(xferp, mReceiveList, is_priority); + addToList(file_xfer_p, mReceiveList, is_priority); // Remove any file by the same name that happens to be lying // around. @@ -447,7 +423,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename, LLFile::remove(local_filename, ENOENT); } xfer_id = getNextID(); - ((LLXfer_File *)xferp)->initializeRequest( + ((LLXfer_File *)file_xfer_p)->initializeRequest( xfer_id, local_filename, remote_filename, @@ -500,28 +476,32 @@ void LLXferManager::requestVFile(const LLUUID& local_id, void** user_data, BOOL is_priority) { - LLXfer *xferp; + LLXfer_VFile * xfer_p = NULL; - for (xferp = mReceiveList; xferp ; xferp = xferp->mNext) + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); ++iter) { - if (xferp->getXferTypeTag() == LLXfer::XFER_VFILE - && (((LLXfer_VFile*)xferp)->matchesLocalFile(local_id, type)) - && (((LLXfer_VFile*)xferp)->matchesRemoteFile(remote_id, type)) - && (remote_host == xferp->mRemoteHost) - && (callback == xferp->mCallback) - && (user_data == xferp->mCallbackDataHandle)) - + if ((*iter)->getXferTypeTag() == LLXfer::XFER_VFILE) { - // cout << "requested a xfer already in progress" << endl; - return; + xfer_p = (LLXfer_VFile*) (*iter); + if (xfer_p->matchesLocalFile(local_id, type) + && xfer_p->matchesRemoteFile(remote_id, type) + && (remote_host == xfer_p->mRemoteHost) + && (callback == xfer_p->mCallback) + && (user_data == xfer_p->mCallbackDataHandle)) + + { + // Have match, already in progress, don't add a duplicate + return; + } } } - xferp = (LLXfer *) new LLXfer_VFile(); - if (xferp) + xfer_p = new LLXfer_VFile(); + if (xfer_p) { - addToList(xferp, mReceiveList, is_priority); - ((LLXfer_VFile *)xferp)->initializeRequest(getNextID(), + addToList(xfer_p, mReceiveList, is_priority); + ((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(), vfs, local_id, remote_id, @@ -663,7 +643,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user if (result == LL_ERR_CANNOT_OPEN_FILE) { xferp->abort(LL_ERR_CANNOT_OPEN_FILE); - removeXfer(xferp,&mReceiveList); + removeXfer(xferp,mReceiveList); startPendingDownloads(); return; } @@ -688,7 +668,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user if (isLastPacket(packetnum)) { xferp->processEOF(); - removeXfer(xferp,&mReceiveList); + removeXfer(xferp,mReceiveList); startPendingDownloads(); } } @@ -708,6 +688,7 @@ void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 pac mesgsys->addU64Fast(_PREHASH_ID, id); mesgsys->addU32Fast(_PREHASH_Packet, packetnum); + // Ignore a circuit failure here, we'll catch it with another message mesgsys->sendMessage(remote_host); } @@ -825,7 +806,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user LLXfer *xferp; if (uuid != LLUUID::null) - { + { // Request for an asset - use a VFS file if(NULL == LLAssetType::lookup(type)) { LL_WARNS() << "Invalid type for xfer request: " << uuid << ":" @@ -844,8 +825,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type); if (xferp) { - xferp->mNext = mSendList; - mSendList = xferp; + mSendList.push_front(xferp); result = xferp->startSend(id,mesgsys->getSender()); } else @@ -854,7 +834,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user } } else if (!local_filename.empty()) - { + { // Was given a file name to send // See DEV-21775 for detailed security issues if (local_path == LL_PATH_NONE) @@ -912,8 +892,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user if (xferp) { - xferp->mNext = mSendList; - mSendList = xferp; + mSendList.push_front(xferp); result = xferp->startSend(id,mesgsys->getSender()); } else @@ -922,7 +901,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user } } else - { + { // no uuid or filename - use the ID sent char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ LL_INFOS() << "starting memory transfer: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " @@ -946,7 +925,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user if (xferp) { xferp->abort(result); - removeXfer(xferp,&mSendList); + removeXfer(xferp, mSendList); } else // can happen with a memory transfer not found { @@ -960,24 +939,86 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user mesgsys->sendMessage(mesgsys->getSender()); } } - else if(xferp && (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit)) + else if(xferp) { - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); -// LL_INFOS() << "***STARTING XFER IMMEDIATELY***" << LL_ENDL; - } - else - { - if(xferp) + // Figure out how many transfers the host has requested + LLHostStatus *host_statusp = findHostStatus(xferp->mRemoteHost); + if (host_statusp) { - LL_INFOS() << " queueing xfer request, " << numPendingXfers(xferp->mRemoteHost) << " ahead of this one" << LL_ENDL; + if (host_statusp->mNumActive < mMaxOutgoingXfersPerCircuit) + { // Not many transfers in progress already, so start immediately + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + LL_DEBUGS("Xfer") << "Starting xfer ID " << U64_to_str(id) << " immediately" << LL_ENDL; + } + else if (mHardLimitOutgoingXfersPerCircuit == 0 || + (host_statusp->mNumActive + host_statusp->mNumPending) < mHardLimitOutgoingXfersPerCircuit) + { // Must close the file handle and wait for earlier ones to complete + LL_INFOS("Xfer") << " queueing xfer request id " << U64_to_str(id) << ", " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + xferp->closeFileHandle(); // Close the file handle until we're ready to send again + } + else if (mHardLimitOutgoingXfersPerCircuit > 0) + { // Way too many requested ... it's time to stop being nice and kill the circuit + xferp->closeFileHandle(); // Close the file handle in any case + LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(xferp->mRemoteHost); + if (cdp) + { + if (cdp->getTrusted()) + { // Trusted internal circuit - don't kill it + LL_WARNS("Xfer") << "Trusted circuit to " << xferp->mRemoteHost << " has too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + } + else + { // Untrusted circuit - time to stop messing around and kill it + LL_WARNS("Xfer") << "Killing circuit to " << xferp->mRemoteHost << " for having too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } + else + { // WTF? Why can't we find a circuit? Try to kill it off + LL_WARNS("Xfer") << "Backlog with circuit to " << xferp->mRemoteHost << " with too many xfer requests in the queue " + << host_statusp->mNumActive << " active and " + << host_statusp->mNumPending << " pending ahead of this one" + << " but no LLCircuitData found???" + << LL_ENDL; + gMessageSystem->disableCircuit(xferp->mRemoteHost); + } + } } else { - LL_WARNS() << "LLXferManager::processFileRequest() - no xfer found!" - << LL_ENDL; + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no LLHostStatus found for id " << U64_to_str(id) + << " host " << xferp->mRemoteHost << LL_ENDL; } } + else + { + LL_WARNS("Xfer") << "LLXferManager::processFileRequest() - no xfer found for id " << U64_to_str(id) << LL_ENDL; + } +} + +/////////////////////////////////////////////////////////// + +// Return true if host is in a transfer-flood sitation. Same check for both internal and external hosts +bool LLXferManager::isHostFlooded(const LLHost & host) +{ + bool flooded = false; + LLHostStatus *host_statusp = findHostStatus(host); + if (host_statusp) + { + flooded = (mHardLimitOutgoingXfersPerCircuit > 0 && + (host_statusp->mNumActive + host_statusp->mNumPending) >= (S32)(mHardLimitOutgoingXfersPerCircuit * 0.8f)); + } + + return flooded; } @@ -1002,91 +1043,103 @@ void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*use } else { - removeXfer(xferp, &mSendList); + removeXfer(xferp, mSendList); } } } /////////////////////////////////////////////////////////// -void LLXferManager::retransmitUnackedPackets () +void LLXferManager::retransmitUnackedPackets() { LLXfer *xferp; - LLXfer *delp; - xferp = mReceiveList; - while(xferp) + + xfer_list_t::iterator iter = mReceiveList.begin(); + while (iter != mReceiveList.end()) { + xferp = (*iter); if (xferp->mStatus == e_LL_XFER_IN_PROGRESS) { // if the circuit dies, abort if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost )) { - LL_INFOS() << "Xfer found in progress on dead circuit, aborting" << LL_ENDL; + LL_WARNS("Xfer") << "Xfer found in progress on dead circuit, aborting transfer to " + << xferp->mRemoteHost.getIPandPort() + << LL_ENDL; xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE; xferp->processEOF(); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mReceiveList); + + iter = mReceiveList.erase(iter); // iter is set to next one after the deletion point + delete (xferp); continue; } } - xferp = xferp->mNext; + ++iter; } - xferp = mSendList; updateHostStatus(); + F32 et; - while (xferp) + iter = mSendList.begin(); + while (iter != mSendList.end()) { + xferp = (*iter); if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT)) { if (xferp->mRetries > LL_PACKET_RETRY_LIMIT) { LL_INFOS() << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << LL_ENDL; xferp->abort(LL_ERR_TCP_TIMEOUT); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + iter = mSendList.erase(iter); + delete xferp; + continue; } else { LL_INFOS() << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << LL_ENDL; xferp->resendLastPacket(); - xferp = xferp->mNext; } } else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT)) { LL_INFOS() << "registered xfer never requested, xfer dropped" << LL_ENDL; xferp->abort(LL_ERR_TCP_TIMEOUT); - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + iter = mSendList.erase(iter); + delete xferp; + continue; } else if (xferp->mStatus == e_LL_XFER_ABORTED) { LL_WARNS() << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << LL_ENDL; - delp = xferp; - xferp = xferp->mNext; - removeXfer(delp,&mSendList); + iter = mSendList.erase(iter); + delete xferp; + continue; } else if (xferp->mStatus == e_LL_XFER_PENDING) { // LL_INFOS() << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << LL_ENDL; if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit) { -// LL_INFOS() << "bumping pending xfer to active" << LL_ENDL; - xferp->sendNextPacket(); - changeNumActiveXfers(xferp->mRemoteHost,1); - } - xferp = xferp->mNext; + if (xferp->reopenFileHandle()) + { + LL_WARNS("Xfer") << "Error re-opening file handle for xfer ID " << U64_to_str(xferp->mID) + << " to host " << xferp->mRemoteHost << LL_ENDL; + xferp->abort(LL_ERR_CANNOT_OPEN_FILE); + iter = mSendList.erase(iter); + delete xferp; + continue; + } + else + { // No error re-opening the file, send the first packet + LL_DEBUGS("Xfer") << "Moving pending xfer ID " << U64_to_str(xferp->mID) << " to active" << LL_ENDL; + xferp->sendNextPacket(); + changeNumActiveXfers(xferp->mRemoteHost,1); + } + } } - else - { - xferp = xferp->mNext; - } - } + ++iter; + } // end while() loop // // HACK - if we're using xfer confirm throttling, throttle our xfer confirms here @@ -1124,7 +1177,7 @@ void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code) { xferp->mCallbackResult = result_code; xferp->processEOF(); //should notify requester - removeXfer(xferp, &mReceiveList); + removeXfer(xferp, mReceiveList); } // Since already removed or marked as aborted no need // to wait for processAbort() to start new download @@ -1148,7 +1201,7 @@ void LLXferManager::processAbort (LLMessageSystem *mesgsys, void ** /*user_data* { xferp->mCallbackResult = result_code; xferp->processEOF(); - removeXfer(xferp, &mReceiveList); + removeXfer(xferp, mReceiveList); startPendingDownloads(); } } @@ -1164,12 +1217,15 @@ void LLXferManager::startPendingDownloads() // requests get pushed toward the back. Thus, if we didn't do a // stateful iteration, it would be possible for old requests to // never start. - LLXfer* xferp = mReceiveList; + LLXfer* xferp; std::list pending_downloads; S32 download_count = 0; S32 pending_count = 0; - while(xferp) + for (xfer_list_t::iterator iter = mReceiveList.begin(); + iter != mReceiveList.end(); + ++iter) { + xferp = (*iter); if(xferp->mStatus == e_LL_XFER_PENDING) { ++pending_count; @@ -1179,7 +1235,6 @@ void LLXferManager::startPendingDownloads() { ++download_count; } - xferp = xferp->mNext; } S32 start_count = mMaxIncomingXfers - download_count; @@ -1209,29 +1264,15 @@ void LLXferManager::startPendingDownloads() /////////////////////////////////////////////////////////// -void LLXferManager::addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority) +void LLXferManager::addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_priority) { if(is_priority) { - xferp->mNext = NULL; - LLXfer* next = head; - if(next) - { - while(next->mNext) - { - next = next->mNext; - } - next->mNext = xferp; - } - else - { - head = xferp; - } + xfer_list.push_back(xferp); } else { - xferp->mNext = head; - head = xferp; + xfer_list.push_front(xferp); } } diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h index d258f0a5ce..ebe8e57ee2 100644 --- a/indra/llmessage/llxfermanager.h +++ b/indra/llmessage/llxfermanager.h @@ -77,6 +77,7 @@ class LLXferManager protected: S32 mMaxOutgoingXfersPerCircuit; + S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection S32 mMaxIncomingXfers; BOOL mUseAckThrottling; // Use ack throttling to cap file xfer bandwidth @@ -92,8 +93,10 @@ class LLXferManager HIGH_PRIORITY = TRUE, }; - LLXfer *mSendList; - LLXfer *mReceiveList; + // Linked FIFO list, add to the front and pull from back + typedef std::deque xfer_list_t; + xfer_list_t mSendList; + xfer_list_t mReceiveList; typedef std::list status_list_t; status_list_t mOutgoingHosts; @@ -102,7 +105,7 @@ class LLXferManager protected: // implementation methods virtual void startPendingDownloads(); - virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority); + virtual void addToList(LLXfer* xferp, xfer_list_t & list, BOOL is_priority); std::multiset mExpectedTransfers; // files that are authorized to transfer out std::multiset mExpectedRequests; // files that are authorized to be downloaded on top of @@ -117,14 +120,18 @@ class LLXferManager void setAckThrottleBPS(const F32 bps); // list management routines - virtual LLXfer *findXfer(U64 id, LLXfer *list_head); - virtual void removeXfer (LLXfer *delp, LLXfer **list_head); + virtual LLXfer *findXfer(U64 id, xfer_list_t & xfer_list); + virtual void removeXfer (LLXfer *delp, xfer_list_t & xfer_list); + + LLHostStatus * findHostStatus(const LLHost &host); virtual U32 numActiveListEntries(LLXfer *list_head); virtual S32 numActiveXfers(const LLHost &host); virtual S32 numPendingXfers(const LLHost &host); + virtual void changeNumActiveXfers(const LLHost &host, S32 delta); virtual void setMaxOutgoingXfersPerCircuit (S32 max_num); + virtual void setHardLimitOutgoingXfersPerCircuit(S32 max_num); virtual void setMaxIncomingXfers(S32 max_num); virtual void updateHostStatus(); virtual void printHostStatus(); @@ -136,8 +143,6 @@ class LLXferManager virtual S32 decodePacketNum(S32 packet_num); virtual BOOL isLastPacket(S32 packet_num); - virtual U64 registerXfer(const void *datap, const S32 length); - // file requesting routines // .. to file virtual U64 requestFile(const std::string& local_filename, @@ -204,6 +209,8 @@ class LLXferManager // error handling void abortRequestById(U64 xfer_id, S32 result_code); virtual void processAbort (LLMessageSystem *mesgsys, void **user_data); + + virtual bool isHostFlooded(const LLHost & host); }; extern LLXferManager* gXferManager; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 1662a7fd14..d00332f5ea 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -818,6 +818,29 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (obj) { + +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) + items.push_back(std::string("Copy Separator")); + + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable() || isLibraryItem()) + { + disabled_items.push_back(std::string("Cut")); + } + + items.push_back(std::string("Copy")); + if (!isItemCopyable() && !isItemLinkable()) + { + disabled_items.push_back(std::string("Copy")); + } +// [/SL:KB] + //items.push_back(std::string("Copy Separator")); + //items.push_back(std::string("Copy")); + //if (!isItemCopyable()) + //{ + // disabled_items.push_back(std::string("Copy")); + //} + if (obj->getIsLinkType()) { items.push_back(std::string("Find Original")); @@ -864,14 +887,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) - //items.push_back(std::string("Copy Separator")); - // - //items.push_back(std::string("Copy")); - //if (!isItemCopyable()) - //{ - // disabled_items.push_back(std::string("Copy")); - //} - //items.push_back(std::string("Cut")); //if (!isItemMovable() || !isItemRemovable()) //{ @@ -895,22 +910,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } } - -// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0) - items.push_back(std::string("Copy Separator")); - - items.push_back(std::string("Cut")); - if (!isItemMovable() || !isItemRemovable() || isLibraryItem()) - { - disabled_items.push_back(std::string("Cut")); - } - - items.push_back(std::string("Copy")); - if (!isItemCopyable() && !isItemLinkable()) - { - disabled_items.push_back(std::string("Copy")); - } -// [/SL:KB] } // Don't allow items to be pasted directly into the COF or the inbox @@ -2324,19 +2323,15 @@ BOOL LLItemBridge::isItemCopyable() const */ -// // You can never copy a link. -// if (item->getIsLinkType()) // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a // We'll allow copying a link if: // - its target is available // - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case] if (item->getIsLinkType()) -// [/SL:KB] { return (NULL != item->getLinkedItem()); } -// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a // User can copy the item if: // - the item (or its target in the case of a link) is "copy" // - and/or if the item (or its target in the case of a link) has a linkable asset type @@ -4133,13 +4128,20 @@ void LLFolderBridge::perform_pasteFromClipboard() break; } } +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a +// else if (item->getIsLinkType()) +// { +// link_inventory_object(parent_id, item_id, +// LLPointer(NULL)); + // } +// [/SL:KB] else { // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a - if (item->getPermissions().allowCopyBy(gAgent.getID())) - { + if (item->getPermissions().allowCopyBy(gAgent.getID())) + { // [/SL:KB] - copy_inventory_item( + copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), @@ -4147,15 +4149,15 @@ void LLFolderBridge::perform_pasteFromClipboard() std::string(), LLPointer(NULL)); // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a - } - else if (LLAssetType::lookupIsLinkType(item->getActualType())) - { - LLInventoryObject::const_object_list_t obj_array; - obj_array.push_back(LLConstPointer(item)); - link_inventory_array(parent_id, - obj_array, - LLPointer(NULL)); - } + } + else if (LLAssetType::lookupIsLinkType(item->getActualType())) + { + LLInventoryObject::const_object_list_t obj_array; + obj_array.push_back(LLConstPointer(item)); + link_inventory_array(parent_id, + obj_array, + LLPointer(NULL)); + } // [/SL:KB] } } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 71f678dd31..e6987b1ab1 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -434,10 +434,11 @@ void copy_inventory_category(LLInventoryModel* model, LLInventoryItem* item = *iter; LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid)); - // FIRE-21719: Copy-pasting a folder doesn't copy contained links - //if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - if (!item->getIsLinkType() && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - // + if (item->getIsLinkType()) + { + link_inventory_object(new_cat_uuid, item->getLinkedUUID(), cb); + } + else if(!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { // If the item is nocopy, we do nothing or, optionally, move it if (move_no_copy_items) @@ -449,12 +450,6 @@ void copy_inventory_category(LLInventoryModel* model, // Decrement the count in root_id since that one item won't be copied over LLMarketplaceData::instance().decrementValidationWaiting(root_id); } - // FIRE-21719: Copy-pasting a folder doesn't copy contained links - else if (item->getIsLinkType()) - { - link_inventory_object(new_cat_uuid, item->getLinkedUUID(), cb); - } - // else { copy_inventory_item( diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 59d60aef77..20babe62cb 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -360,6 +360,9 @@ const U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes const long SMALL_MESH_XFER_TIMEOUT = 120L; // Seconds to complete xfer, small mesh downloads const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large downloads +const U32 DOWNLOAD_RETRY_LIMIT = 8; +const F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds + // Would normally like to retry on uploads as some // retryable failures would be recoverable. Unfortunately, // the mesh service is using 500 (retryable) rather than @@ -528,6 +531,24 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, } } +void RequestStats::updateTime() +{ + U32 modifier = 1 << mRetries; // before ++ + mRetries++; + mTimer.reset(); + mTimer.setTimerExpirySec(DOWNLOAD_RETRY_DELAY * (F32)modifier); // up to 32s, 64 total wait +} + +bool RequestStats::canRetry() const +{ + return mRetries < DOWNLOAD_RETRY_LIMIT; +} + +bool RequestStats::isDelayed() const +{ + return mTimer.getStarted() && !mTimer.hasExpired(); +} + LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material) { LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData); @@ -905,142 +926,225 @@ void LLMeshRepoThread::run() sRequestWaterLevel = mHttpRequestSet.size(); // Stats data update // NOTE: order of queue processing intentionally favors LOD requests over header requests + // Todo: we are processing mLODReqQ, mHeaderReqQ, mSkinRequests, mDecompositionRequests and mPhysicsShapeRequests + // in relatively similar manners, remake code to simplify/unify the process, + // like processRequests(&requestQ, fetchFunction); which does same thing for each element - while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - if (! mMutex) - { - break; - } - mMutex->lock(); - LODRequest req = mLODReqQ.front(); - mLODReqQ.pop(); - LLMeshRepository::sLODProcessing--; - mMutex->unlock(); + if (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + std::list incomplete; + while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + if (!mMutex) + { + break; + } - // Todo: this and other cases shouldn't retry indefinitely, at the very least do as with mDecompositionRequests - if (!fetchMeshLOD(req.mMeshParams, req.mLOD)) // failed, resubmit - { - mMutex->lock(); - mLODReqQ.push(req); - ++LLMeshRepository::sLODProcessing; - mMutex->unlock(); - } - } + mMutex->lock(); + LODRequest req = mLODReqQ.front(); + mLODReqQ.pop(); + LLMeshRepository::sLODProcessing--; + mMutex->unlock(); + if (req.isDelayed()) + { + // failed to load before, wait a bit + incomplete.push_front(req); + } + else if (!fetchMeshLOD(req.mMeshParams, req.mLOD, req.canRetry())) + { + if (req.canRetry()) + { + // failed, resubmit + req.updateTime(); + incomplete.push_front(req); + } + else + { + // too many fails + mUnavailableQ.push(req); + LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; + } + } + } - while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - if (! mMutex) - { - break; - } - mMutex->lock(); - HeaderRequest req = mHeaderReqQ.front(); - mHeaderReqQ.pop(); - mMutex->unlock(); - if (!fetchMeshHeader(req.mMeshParams))//failed, resubmit - { - mMutex->lock(); - mHeaderReqQ.push(req) ; - mMutex->unlock(); - } - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (std::list::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++) + { + mLODReqQ.push(*iter); + ++LLMeshRepository::sLODProcessing; + } + } + } - // For the final three request lists, similar goal to above but - // slightly different queue structures. Stay off the mutex when - // performing long-duration actions. + if (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + std::list incomplete; + while (!mHeaderReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + if (!mMutex) + { + break; + } - if (mHttpRequestSet.size() < sRequestHighWater - && (! mSkinRequests.empty() - || ! mDecompositionRequests.empty() - || ! mPhysicsShapeRequests.empty())) - { - // Something to do probably, lock and double-check. We don't want - // to hold the lock long here. That will stall main thread activities - // so we bounce it. + mMutex->lock(); + HeaderRequest req = mHeaderReqQ.front(); + mHeaderReqQ.pop(); + mMutex->unlock(); + if (req.isDelayed()) + { + // failed to load before, wait a bit + incomplete.push_front(req); + } + else if (!fetchMeshHeader(req.mMeshParams, req.canRetry())) + { + if (req.canRetry()) + { + //failed, resubmit + req.updateTime(); + incomplete.push_front(req); + } + else + { + LL_DEBUGS() << "mHeaderReqQ failed: " << req.mMeshParams << LL_ENDL; + } + } + } - mMutex->lock(); - if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set incomplete; - std::set::iterator iter(mSkinRequests.begin()); - while (iter != mSkinRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mSkinRequests.erase(iter); - mMutex->unlock(); + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (std::list::iterator iter = incomplete.begin(); iter != incomplete.end(); iter++) + { + mHeaderReqQ.push(*iter); + } + } + } - if (! fetchMeshSkinInfo(mesh_id)) - { - incomplete.insert(mesh_id); - } + // For the final three request lists, similar goal to above but + // slightly different queue structures. Stay off the mutex when + // performing long-duration actions. - mMutex->lock(); - iter = mSkinRequests.begin(); - } + if (mHttpRequestSet.size() < sRequestHighWater + && (!mSkinRequests.empty() + || !mDecompositionRequests.empty() + || !mPhysicsShapeRequests.empty())) + { + // Something to do probably, lock and double-check. We don't want + // to hold the lock long here. That will stall main thread activities + // so we bounce it. - if (! incomplete.empty()) - { - mSkinRequests.insert(incomplete.begin(), incomplete.end()); - } - } + if (!mSkinRequests.empty()) + { + std::set incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set::iterator iter = mSkinRequests.begin(); + UUIDBasedRequest req = *iter; + mSkinRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshSkinInfo(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL; + } + } + } - // holding lock, try next list - // *TODO: For UI/debug-oriented lists, we might drop the fine- - // grained locking as there's a lowered expectation of smoothness - // in these cases. - if (! mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set incomplete; - std::set::iterator iter(mDecompositionRequests.begin()); - while (iter != mDecompositionRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mDecompositionRequests.erase(iter); - mMutex->unlock(); - - if (! fetchMeshDecomposition(mesh_id)) - { - incomplete.insert(mesh_id); - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mSkinRequests.insert(incomplete.begin(), incomplete.end()); + } + } - mMutex->lock(); - iter = mDecompositionRequests.begin(); - } + // holding lock, try next list + // *TODO: For UI/debug-oriented lists, we might drop the fine- + // grained locking as there's a lowered expectation of smoothness + // in these cases. + if (!mDecompositionRequests.empty()) + { + std::set incomplete; + while (!mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set::iterator iter = mDecompositionRequests.begin(); + UUIDBasedRequest req = *iter; + mDecompositionRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshDecomposition(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mDecompositionRequests failed: " << req.mId << LL_ENDL; + } + } + } - if (! incomplete.empty()) - { - mDecompositionRequests.insert(incomplete.begin(), incomplete.end()); - } - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mDecompositionRequests.insert(incomplete.begin(), incomplete.end()); + } + } - // holding lock, final list - if (! mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - std::set incomplete; - std::set::iterator iter(mPhysicsShapeRequests.begin()); - while (iter != mPhysicsShapeRequests.end() && mHttpRequestSet.size() < sRequestHighWater) - { - LLUUID mesh_id = *iter; - mPhysicsShapeRequests.erase(iter); - mMutex->unlock(); - - if (! fetchMeshPhysicsShape(mesh_id)) - { - incomplete.insert(mesh_id); - } + // holding lock, final list + if (!mPhysicsShapeRequests.empty()) + { + std::set incomplete; + while (!mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { + mMutex->lock(); + std::set::iterator iter = mPhysicsShapeRequests.begin(); + UUIDBasedRequest req = *iter; + mPhysicsShapeRequests.erase(iter); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.insert(req); + } + else if (!fetchMeshPhysicsShape(req.mId)) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.insert(req); + } + else + { + LL_DEBUGS() << "mPhysicsShapeRequests failed: " << req.mId << LL_ENDL; + } + } + } - mMutex->lock(); - iter = mPhysicsShapeRequests.begin(); - } - - if (! incomplete.empty()) - { - mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end()); - } - } - mMutex->unlock(); - } + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + mPhysicsShapeRequests.insert(incomplete.begin(), incomplete.end()); + } + } + } // For dev purposes only. A dynamic change could make this false // and that shouldn't assert. @@ -1062,19 +1166,19 @@ void LLMeshRepoThread::run() // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) { - mSkinRequests.insert(mesh_id); + mSkinRequests.insert(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshDecomposition(const LLUUID& mesh_id) { - mDecompositionRequests.insert(mesh_id); + mDecompositionRequests.insert(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id) { - mPhysicsShapeRequests.insert(mesh_id); + mPhysicsShapeRequests.insert(UUIDBasedRequest(mesh_id)); } void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) @@ -1601,7 +1705,7 @@ void LLMeshRepoThread::decActiveHeaderRequests() } //return false if failed to get header -bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry) { ++LLMeshRepository::sMeshRequestCount; @@ -1655,7 +1759,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) << LL_ENDL; retval = false; } - else + else if (can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); @@ -1666,7 +1770,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) } //return false if failed to get mesh lod. -bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry) { if (!mHeaderMutex) { @@ -1699,7 +1803,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh LOD, size: " << size << LL_ENDL; + LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; // todo: for now it will result in indefinite constant retries, should result in timeout // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) return false; @@ -1751,12 +1855,16 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) << LL_ENDL; retval = false; } - else + else if (can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); // *NOTE: Allowing a re-request, not marking as unavailable. Is that correct? } + else + { + mUnavailableQ.push(LODRequest(mesh_params, lod)); + } } else { diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 37edbb01e1..26de4d5f56 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -179,6 +179,21 @@ public: }; +class RequestStats +{ +public: + RequestStats() : mRetries(0) {}; + + void updateTime(); + bool canRetry() const; + bool isDelayed() const; + U32 getRetries() { return mRetries; } + +private: + U32 mRetries; + LLFrameTimer mTimer; +}; + class LLMeshRepoThread : public LLThread { public: @@ -199,14 +214,14 @@ public: mesh_header_map mMeshHeader; std::map mMeshHeaderSize; - - class HeaderRequest + + class HeaderRequest : public RequestStats { public: const LLVolumeParams mMeshParams; HeaderRequest(const LLVolumeParams& mesh_params) - : mMeshParams(mesh_params) + : RequestStats(), mMeshParams(mesh_params) { } @@ -216,7 +231,7 @@ public: } }; - class LODRequest + class LODRequest : public RequestStats { public: LLVolumeParams mMeshParams; @@ -224,7 +239,7 @@ public: F32 mScore; LODRequest(const LLVolumeParams& mesh_params, S32 lod) - : mMeshParams(mesh_params), mLOD(lod), mScore(0.f) + : RequestStats(), mMeshParams(mesh_params), mLOD(lod), mScore(0.f) { } }; @@ -236,7 +251,22 @@ public: return lhs.mScore > rhs.mScore; // greatest = first } }; - + + class UUIDBasedRequest : public RequestStats + { + public: + LLUUID mId; + + UUIDBasedRequest(const LLUUID& id) + : RequestStats(), mId(id) + { + } + + bool operator<(const UUIDBasedRequest& rhs) const + { + return mId < rhs.mId; + } + }; class LoadedMesh { @@ -253,16 +283,16 @@ public: }; //set of requested skin info - std::set mSkinRequests; + std::set mSkinRequests; // list of completed skin info requests std::list mSkinInfoQ; //set of requested decompositions - std::set mDecompositionRequests; + std::set mDecompositionRequests; //set of requested physics shapes - std::set mPhysicsShapeRequests; + std::set mPhysicsShapeRequests; // list of completed Decomposition info requests std::list mDecompositionQ; @@ -312,8 +342,8 @@ public: void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); - bool fetchMeshHeader(const LLVolumeParams& mesh_params); - bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true); bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 12adf0bc28..609d6f6c11 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -215,16 +215,6 @@ BOOL LLPanelGroup::postBuild() button = getChild("btn_chat"); button->setClickedCallback(onBtnGroupChatClicked, this); - // Might not exist - //button = getChild("btn_cancel"); - //button->setVisible(false); button->setEnabled(true); - button = findChild("btn_cancel"); - if (button) - { - button->setVisible(false); button->setEnabled(true); - } - // - button = getChild("btn_refresh"); button->setClickedCallback(onBtnRefresh, this); @@ -233,8 +223,6 @@ BOOL LLPanelGroup::postBuild() childSetCommitCallback("back",boost::bind(&LLPanelGroup::onBackBtnClick,this),NULL); childSetCommitCallback("btn_create",boost::bind(&LLPanelGroup::onBtnCreate,this),NULL); - - childSetCommitCallback("btn_cancel",boost::bind(&LLPanelGroup::onBtnCancel,this),NULL); LLPanelGroupTab* panel_general = findChild("group_general_tab_panel"); LLPanelGroupTab* panel_roles = findChild("group_roles_tab_panel"); @@ -373,11 +361,6 @@ void LLPanelGroup::onBtnJoin() LLGroupActions::join(mID); } -void LLPanelGroup::onBtnCancel() -{ - onBackBtnClick(); -} - void LLPanelGroup::changed(LLGroupChange gc) { for(std::vector::iterator it = mTabs.begin();it!=mTabs.end();++it) diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 1eb13ad491..749677b2b0 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -100,7 +100,6 @@ protected: void onBtnCreate(); void onBackBtnClick(); void onBtnJoin(); - void onBtnCancel(); static void onBtnApply(void*); static void onBtnRefresh(void*); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 5f3f851890..851754a684 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -479,20 +479,12 @@ BOOL LLPanelGroupSubTab::postBuild() { // Hook up the search widgets. bool recurse = true; - // Does not exist on all tabs! - //mSearchEditor = getChild("filter_input", recurse); - //if (!mSearchEditor) - // return FALSE; - - //mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); mSearchEditor = findChild("filter_input", recurse); - - if (mSearchEditor) + if (mSearchEditor) // SubTab doesn't implement this, only some of derived classes { mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2)); } - // return LLPanelGroupTab::postBuild(); } @@ -843,12 +835,8 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - // Might not exist - //mHeader = parent->getChild("members_header", recurse); - //mFooter = parent->getChild("members_footer", recurse); mHeader = parent->findChild("members_header", recurse); mFooter = parent->findChild("members_footer", recurse); - // mMembersList = parent->getChild("member_list", recurse); mAssignedRolesList = parent->getChild("member_assigned_roles", recurse); @@ -2086,12 +2074,8 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - // Might not exist - //mHeader = parent->getChild("roles_header", recurse); - //mFooter = parent->getChild("roles_footer", recurse); mHeader = parent->findChild("roles_header", recurse); mFooter = parent->findChild("roles_footer", recurse); - // mRolesList = parent->getChild("role_list", recurse); @@ -2899,12 +2883,8 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - // Might not exist - //mHeader = parent->getChild("actions_header", recurse); - //mFooter = parent->getChild("actions_footer", recurse); mHeader = parent->findChild("actions_header", recurse); mFooter = parent->findChild("actions_footer", recurse); - // mActionDescription = parent->getChild("action_description", recurse); @@ -3110,14 +3090,10 @@ BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - - // Might not exist - //mHeader = parent->getChild("banlist_header", recurse); - //mFooter = parent->getChild("banlist_footer", recurse); - mHeader = parent->findChild("banlist_header", recurse); - mFooter = parent->findChild("banlist_footer", recurse); - // - + + mHeader = parent->findChild("banlist_header", recurse); + mFooter = parent->findChild("banlist_footer", recurse); + mBanList = parent->getChild("ban_list", recurse); mCreateBanButton = parent->getChild("ban_create", recurse); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 01e961cf20..b708f3a84d 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -139,7 +139,7 @@ protected: BOOL is_owner_role); protected: - LLPanel* mHeader; + LLPanel* mHeader; // Might not be present in xui of derived class (NULL) LLPanel* mFooter; LLFilterEditor* mSearchEditor; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 976b5bf74b..1cee7de9ee 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -107,9 +107,7 @@ public: static LLTaskInvFVBridge* createObjectBridge(LLPanelObjectInventory* panel, LLInventoryObject* object); void showProperties(); - void buyItem(); S32 getPrice(); - static bool commitBuyItem(const LLSD& notification, const LLSD& response); // LLFolderViewModelItemInventory functionality virtual const std::string& getName() const; @@ -206,76 +204,6 @@ void LLTaskInvFVBridge::showProperties() show_task_item_profile(mUUID, mPanel->getTaskUUID()); } -struct LLBuyInvItemData -{ - LLUUID mTaskID; - LLUUID mItemID; - LLAssetType::EType mType; - - LLBuyInvItemData(const LLUUID& task, - const LLUUID& item, - LLAssetType::EType type) : - mTaskID(task), mItemID(item), mType(type) - {} -}; - -void LLTaskInvFVBridge::buyItem() -{ - LL_INFOS() << "LLTaskInvFVBridge::buyItem()" << LL_ENDL; - LLInventoryItem* item = findItem(); - if(!item || !item->getSaleInfo().isForSale()) return; - LLBuyInvItemData* inv = new LLBuyInvItemData(mPanel->getTaskUUID(), - mUUID, - item->getType()); - - const LLSaleInfo& sale_info = item->getSaleInfo(); - const LLPermissions& perm = item->getPermissions(); - const std::string owner_name; // no owner name currently... FIXME? - - LLViewerObject* obj; - if( ( obj = gObjectList.findObject( mPanel->getTaskUUID() ) ) && obj->isAttachment() ) - { - LLNotificationsUtil::add("Cannot_Purchase_an_Attachment"); - LL_INFOS() << "Attempt to purchase an attachment" << LL_ENDL; - delete inv; - } - else - { - LLSD args; - args["PRICE"] = llformat("%d",sale_info.getSalePrice()); - args["OWNER"] = owner_name; - if (sale_info.getSaleType() != LLSaleInfo::FS_CONTENTS) - { - U32 next_owner_mask = perm.getMaskNextOwner(); - args["MODIFYPERM"] = LLTrans::getString((next_owner_mask & PERM_MODIFY) ? "PermYes" : "PermNo"); - args["COPYPERM"] = LLTrans::getString((next_owner_mask & PERM_COPY) ? "PermYes" : "PermNo"); - args["RESELLPERM"] = LLTrans::getString((next_owner_mask & PERM_TRANSFER) ? "PermYes" : "PermNo"); - } - - std::string alertdesc; - switch(sale_info.getSaleType()) - { - case LLSaleInfo::FS_ORIGINAL: - alertdesc = owner_name.empty() ? "BuyOriginalNoOwner" : "BuyOriginal"; - break; - case LLSaleInfo::FS_CONTENTS: - alertdesc = owner_name.empty() ? "BuyContentsNoOwner" : "BuyContents"; - break; - case LLSaleInfo::FS_COPY: - default: - alertdesc = owner_name.empty() ? "BuyCopyNoOwner" : "BuyCopy"; - break; - } - - LLSD payload; - payload["task_id"] = inv->mTaskID; - payload["item_id"] = inv->mItemID; - payload["type"] = inv->mType; - LLNotificationsUtil::add(alertdesc, args, payload, LLTaskInvFVBridge::commitBuyItem); - - delete inv; // Fix for memory leak - } -} S32 LLTaskInvFVBridge::getPrice() { @@ -290,31 +218,6 @@ S32 LLTaskInvFVBridge::getPrice() } } -// static -bool LLTaskInvFVBridge::commitBuyItem(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if(0 == option) - { - LLViewerObject* object = gObjectList.findObject(notification["payload"]["task_id"].asUUID()); - if(!object || !object->getRegion()) return false; - - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_BuyObjectInventory); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_Data); - msg->addUUIDFast(_PREHASH_ObjectID, notification["payload"]["task_id"].asUUID()); - msg->addUUIDFast(_PREHASH_ItemID, notification["payload"]["item_id"].asUUID()); - msg->addUUIDFast(_PREHASH_FolderID, - gInventory.findCategoryUUIDForType((LLFolderType::EType)notification["payload"]["type"].asInteger())); - msg->sendReliable(object->getRegion()->getHost()); - } - return false; -} - const std::string& LLTaskInvFVBridge::getName() const { return mName; @@ -679,29 +582,7 @@ BOOL LLTaskInvFVBridge::dragOrDrop(MASK mask, BOOL drop, // virtual void LLTaskInvFVBridge::performAction(LLInventoryModel* model, std::string action) { - if (action == "task_buy") - { - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - if (price > 0 && price > gStatusBar->getBalance()) - { - LLStringUtil::format_map_t args; - args["AMOUNT"] = llformat("%d", price); - LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_costs", args), price ); - } - else - { - buyItem(); - } - } - } - else if (action == "task_open") + if (action == "task_open") { openItem(); } @@ -723,42 +604,7 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(!gAgent.allowOperation(PERM_OWNER, item->getPermissions(), - GP_OBJECT_MANIPULATE) - && item->getSaleInfo().isForSale()) - { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; -// -// info << LLTrans::getString("BuyforL$") << price; - info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price; -// - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } - } - else if (canOpenItem()) + if (canOpenItem()) { items.push_back(std::string("Task Open")); // [RLVa:KB] - Checked: 2010-03-01 (RLVa-1.2.0b) | Modified: RLVa-1.1.0a @@ -1105,41 +951,7 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(item->getPermissions().getOwner() != gAgent.getID() - && item->getSaleInfo().isForSale()) - { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; -// -// info << LLTrans::getString("BuyforL$") << price; - info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price; -// - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } - } - else if (canOpenItem()) + if (canOpenItem()) { if (!isItemCopyable()) { @@ -1504,48 +1316,12 @@ void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) return; } - if(item->getPermissions().getOwner() != gAgent.getID() - && item->getSaleInfo().isForSale()) + items.push_back(std::string("Task Open")); + if (!isItemCopyable()) { - items.push_back(std::string("Task Buy")); - - std::string label= LLTrans::getString("Buy"); - // Check the price of the item. - S32 price = getPrice(); - if (-1 == price) - { - LL_WARNS() << "label_buy_task_bridged_item: Invalid price" << LL_ENDL; - } - else - { - std::ostringstream info; -// -// info << LLTrans::getString("BuyforL$") << price; - info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price; -// - label.assign(info.str()); - } - - const LLView::child_list_t *list = menu.getChildList(); - LLView::child_list_t::const_iterator itor; - for (itor = list->begin(); itor != list->end(); ++itor) - { - std::string name = (*itor)->getName(); - LLMenuItemCallGL* menu_itemp = dynamic_cast(*itor); - if (name == "Task Buy" && menu_itemp) - { - menu_itemp->setLabel(label); - } - } - } - else - { - items.push_back(std::string("Task Open")); - if (!isItemCopyable()) - { - disabled_items.push_back(std::string("Task Open")); - } + disabled_items.push_back(std::string("Task Open")); } + items.push_back(std::string("Task Properties")); // Legacy object properties //if ((flags & FIRST_SELECTED_ITEM) == 0) diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index e9a0d32034..b728488a56 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -538,13 +538,6 @@ BOOL LLPanelOutfitEdit::postBuild() mPlusBtn = getChild("plus_btn"); mPlusBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this)); - - // Unused as of 06-12-2017 - //mEditWearableBtn = getChild("edit_wearable_btn"); - //mEditWearableBtn->setEnabled(FALSE); - //mEditWearableBtn->setVisible(FALSE); - //mEditWearableBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this)); - // childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index c8b7033b6c..0d9892784b 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -217,7 +217,6 @@ private: LLFilterEditor* mSearchFilter; LLSaveFolderState* mSavedFolderState; std::string mSearchString; - //LLButton* mEditWearableBtn; // Unused as of 06-12-2017 LLButton* mFolderViewBtn; LLButton* mListViewBtn; LLButton* mPlusBtn; diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 47d041dfd1..9b586381a4 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -208,7 +208,9 @@ BOOL LLPanelPermissions::postBuild() childSetCommitCallback("clickaction",LLPanelPermissions::onCommitClickAction,this); childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this); - // mLabelGroupName = getChild("Group Name Proxy"); + //mLabelGroupName = getChild("Group Name Proxy"); + //mLabelOwnerName = getChild("Owner Name"); + //mLabelCreatorName = getChild("Creator Name"); return TRUE; } @@ -216,6 +218,14 @@ BOOL LLPanelPermissions::postBuild() LLPanelPermissions::~LLPanelPermissions() { + //if (mOwnerCacheConnection.connected()) + //{ + // mOwnerCacheConnection.disconnect(); + //} + //if (mCreatorCacheConnection.connected()) + //{ + // mCreatorCacheConnection.disconnect(); + //} // base class will take care of everything } @@ -230,12 +240,16 @@ void LLPanelPermissions::disableAll() getChildView("Creator:")->setEnabled(FALSE); //getChild("Creator Icon")->setVisible(FALSE); + //mLabelCreatorName->setValue(LLStringUtil::null); + //mLabelCreatorName->setEnabled(FALSE); getChild("Creator Name")->setValue(LLStringUtil::null); getChildView("Creator Name")->setEnabled(FALSE); getChildView("Owner:")->setEnabled(FALSE); //getChild("Owner Icon")->setVisible(FALSE); //getChild("Owner Group Icon")->setVisible(FALSE); + //mLabelOwnerName->setValue(LLStringUtil::null); + //mLabelOwnerName->setEnabled(FALSE); getChild("Owner Name")->setValue(LLStringUtil::null); getChildView("Owner Name")->setEnabled(FALSE); @@ -443,22 +457,29 @@ void LLPanelPermissions::refresh() // style_params.color = link_color; // style_params.readonly_color = link_color; // style_params.is_link = true; // link will be added later -// const LLFontGL* fontp = getChild("Creator Name")->getFont(); +// const LLFontGL* fontp = mLabelCreatorName->getFont(); // style_params.font.name = LLFontGL::nameFromFont(fontp); // style_params.font.size = LLFontGL::sizeFromFont(fontp); // style_params.font.style = "UNDERLINE"; // LLAvatarName av_name; +// style_params.link_href = creator_app_link; // if (LLAvatarNameCache::get(mCreatorID, &av_name)) // { -// // If name isn't present, this will 'request' it and trigger refresh() again -// LLTextBox* text_box = getChild("Creator Name"); -// style_params.link_href = creator_app_link; -// text_box->setText(av_name.getCompleteName(), style_params); +// updateCreatorName(mCreatorID, av_name, style_params); +// } +// else +// { +// if (mCreatorCacheConnection.connected()) +// { +// mCreatorCacheConnection.disconnect(); +// } +// mLabelCreatorName->setText(LLTrans::getString("None")); +// mCreatorCacheConnection = LLAvatarNameCache::get(mCreatorID, boost::bind(&LLPanelPermissions::updateCreatorName, this, _1, _2, style_params)); // } // getChild("Creator Icon")->setValue(mCreatorID); // getChild("Creator Icon")->setVisible(TRUE); -// getChildView("Creator Name")->setEnabled(TRUE); +// mLabelCreatorName->setEnabled(TRUE); // [RLVa:KB] - Moved further down to avoid an annoying flicker when the text is set twice in a row // Update owner text field @@ -474,9 +495,8 @@ void LLPanelPermissions::refresh() // LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mOwnerID); // if (group_data && group_data->isGroupPropertiesDataComplete()) // { - // LLTextBox* text_box = getChild("Owner Name"); // style_params.link_href = owner_app_link; - // text_box->setText(group_data->mName, style_params); + // mLabelOwnerName->setText(group_data->mName, style_params); // getChild("Owner Group Icon")->setIconId(group_data->mInsigniaID); // getChild("Owner Group Icon")->setVisible(TRUE); // getChild("Owner Icon")->setVisible(FALSE); @@ -505,18 +525,27 @@ void LLPanelPermissions::refresh() //} // owner_id = mLastOwnerID; // } + // + // style_params.link_href = owner_app_link; // if (LLAvatarNameCache::get(owner_id, &av_name)) // { - // // If name isn't present, this will 'request' it and trigger refresh() again - // LLTextBox* text_box = getChild("Owner Name"); - // style_params.link_href = owner_app_link; - // text_box->setText(av_name.getCompleteName(), style_params); + // updateOwnerName(owner_id, av_name, style_params); // } + // else + // { + // if (mOwnerCacheConnection.connected()) + // { + // mOwnerCacheConnection.disconnect(); + // } + // mLabelOwnerName->setText(LLTrans::getString("None")); + // mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLPanelPermissions::updateOwnerName, this, _1, _2, style_params)); + // } + // // getChild("Owner Icon")->setValue(owner_id); // getChild("Owner Icon")->setVisible(TRUE); // getChild("Owner Group Icon")->setVisible(FALSE); //} -// getChildView("Owner Name")->setEnabled(TRUE); +// mLabelOwnerName->setEnabled(TRUE); // [RLVa:KB] - Moved further down to avoid an annoying flicker when the text is set twice in a row // [RLVa:KB] - Checked: RLVa-2.0.1 @@ -1137,6 +1166,23 @@ void LLPanelPermissions::refresh() getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); } +//void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params) +//{ +// if (mOwnerCacheConnection.connected()) +// { +// mOwnerCacheConnection.disconnect(); +// } +// mLabelOwnerName->setText(owner_name.getCompleteName(), style_params); +//} +// +//void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params) +//{ +// if (mCreatorCacheConnection.connected()) +// { +// mCreatorCacheConnection.disconnect(); +// } +// mLabelCreatorName->setText(creator_name.getCompleteName(), style_params); +//} // static void LLPanelPermissions::onClickClaim(void*) diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h index fe49939ae1..beabe67408 100644 --- a/indra/newview/llpanelpermissions.h +++ b/indra/newview/llpanelpermissions.h @@ -28,6 +28,7 @@ #define LL_LLPANELPERMISSIONS_H #include "llpanel.h" +#include "llstyle.h" #include "lluuid.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -36,6 +37,8 @@ // Panel for permissions of an object. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//class LLAvatarName; +//class LLTextBox; //class LLNameBox; class LLViewerInventoryItem; class LLViewerObject; @@ -48,6 +51,8 @@ public: /*virtual*/ BOOL postBuild(); + //void updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params); + //void updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params); void refresh(); // refresh all labels as needed protected: @@ -90,10 +95,15 @@ protected: private: // LLNameBox* mLabelGroupName; // group name + //LLTextBox* mLabelOwnerName; + //LLTextBox* mLabelCreatorName; LLUUID mCreatorID; LLUUID mOwnerID; LLUUID mLastOwnerID; + //boost::signals2::connection mOwnerCacheConnection; + //boost::signals2::connection mCreatorCacheConnection; + LLPointer mLastSelectedObject; }; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 678eeaa7fa..8ef3d1bdbc 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -104,12 +104,6 @@ BOOL LLSidepanelAppearance::postBuild() childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this)); - // Disabled as of 12-09-2014 - //mNewOutfitBtn = getChild("newlook_btn"); - //mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this)); - //mNewOutfitBtn->setEnabled(false); - // - mFilterEditor = getChild("Filter"); if (mFilterEditor) { @@ -289,14 +283,6 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked() } } -void LLSidepanelAppearance::onNewOutfitButtonClicked() -{ - if (!mOutfitEdit->getVisible()) - { - mPanelOutfitsInventory->onSave(); - } -} - void LLSidepanelAppearance::showOutfitsInventoryPanel() { toggleWearableEditPanel(FALSE); @@ -351,7 +337,6 @@ void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible) // *TODO: Move these controls to panel_outfits_inventory.xml // so that we don't need to toggle them explicitly. mFilterEditor->setVisible(visible); - //mNewOutfitBtn->setVisible(visible); // Disabled as of 12-09-2014 mCurrOutfitPanel->setVisible(visible); if (visible) @@ -477,8 +462,6 @@ void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *dat // fetched. Alternatively, we could stuff this logic into llagentwearables::makeNewOutfitLinks. void LLSidepanelAppearance::fetchInventory() { - - //mNewOutfitBtn->setEnabled(false); // Disabled as of 12-09-2014 uuid_vec_t ids; LLUUID item_id; for(S32 type = (S32)LLWearableType::WT_SHAPE; type < (S32)LLWearableType::WT_COUNT; ++type) @@ -529,7 +512,6 @@ void LLSidepanelAppearance::fetchInventory() void LLSidepanelAppearance::inventoryFetched() { - //mNewOutfitBtn->setEnabled(true); // Disabled as of 12-09-2014 } void LLSidepanelAppearance::setWearablesLoading(bool val) diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index e08ec7b131..1db7ec4a9c 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -59,7 +59,6 @@ public: void fetchInventory(); void inventoryFetched(); - void onNewOutfitButtonClicked(); void showOutfitsInventoryPanel(); void showOutfitEditPanel(); @@ -99,7 +98,6 @@ private: LLButton* mOpenOutfitBtn; LLButton* mEditAppearanceBtn; - //LLButton* mNewOutfitBtn; // Disabled as of 12-09-2014 LLPanel* mCurrOutfitPanel; LLTextBox* mCurrentLookName; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index e88bf24edc..29ac2e4f07 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -193,11 +193,6 @@ BOOL LLSidepanelInventory::postBuild() mTeleportBtn = mInventoryPanel->getChild("teleport_btn"); mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this)); - // Doesn't exist as of 2015-11-26 - //mOverflowBtn = mInventoryPanel->getChild("overflow_btn"); - //mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this)); - // - mPanelMainInventory = mInventoryPanel->getChild("panel_main_inventory"); mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2)); LLTabContainer* tabs = mPanelMainInventory->getChild("inventory filter tabs"); @@ -570,12 +565,6 @@ void LLSidepanelInventory::onTeleportButtonClicked() performActionOnSelection("teleport"); } -// Doesn't exist as of 2015-11-26 -//void LLSidepanelInventory::onOverflowButtonClicked() -//{ -//} -// - void LLSidepanelInventory::onBackButtonClicked() { showInventoryPanel(); diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 013a382ac7..e34c00d553 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -117,7 +117,6 @@ protected: void onWearButtonClicked(); void onPlayButtonClicked(); void onTeleportButtonClicked(); - //void onOverflowButtonClicked(); // Doesn't exist as of 2015-11-26 public: void onBackButtonClicked(); @@ -127,7 +126,6 @@ private: LLButton* mWearBtn; LLButton* mPlayBtn; LLButton* mTeleportBtn; - //LLButton* mOverflowBtn; // Doesn't exist as of 2015-11-26 LLButton* mShopBtn; bool mInboxEnabled; diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp index baebb2e204..0cff09f022 100644 --- a/indra/newview/llsidepanelinventorysubpanel.cpp +++ b/indra/newview/llsidepanelinventorysubpanel.cpp @@ -50,8 +50,7 @@ LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel(const LLPanel::Params : LLPanel(p), mIsDirty(TRUE), mIsEditing(FALSE), - mCancelBtn(NULL), - mSaveBtn(NULL) + mCancelBtn(NULL) { } @@ -63,24 +62,11 @@ LLSidepanelInventorySubpanel::~LLSidepanelInventorySubpanel() // virtual BOOL LLSidepanelInventorySubpanel::postBuild() { - // Doesn't exist on every sub panel - //mSaveBtn = getChild("save_btn"); - //mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this)); - - //mCancelBtn = getChild("cancel_btn"); - //mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this)); - mSaveBtn = findChild("save_btn"); - if (mSaveBtn) - { - mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this)); - } - mCancelBtn = findChild("cancel_btn"); if (mCancelBtn) { mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this)); } - // return TRUE; } @@ -131,18 +117,10 @@ void LLSidepanelInventorySubpanel::dirty() void LLSidepanelInventorySubpanel::updateVerbs() { - // Doesn't exist on every sub panel - //mSaveBtn->setVisible(mIsEditing); - //mCancelBtn->setVisible(mIsEditing); - if (mSaveBtn) - { - mSaveBtn->setVisible(mIsEditing); - } if (mCancelBtn) { mCancelBtn->setVisible(mIsEditing); } - // } void LLSidepanelInventorySubpanel::onEditButtonClicked() @@ -152,14 +130,6 @@ void LLSidepanelInventorySubpanel::onEditButtonClicked() updateVerbs(); } -void LLSidepanelInventorySubpanel::onSaveButtonClicked() -{ - save(); - setIsEditing(FALSE); - refresh(); - updateVerbs(); -} - void LLSidepanelInventorySubpanel::onCancelButtonClicked() { setIsEditing(FALSE); diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h index b5cf3aaf17..0d18943cbf 100644 --- a/indra/newview/llsidepanelinventorysubpanel.h +++ b/indra/newview/llsidepanelinventorysubpanel.h @@ -62,9 +62,7 @@ protected: // protected: void onEditButtonClicked(); - void onSaveButtonClicked(); void onCancelButtonClicked(); - LLButton* mSaveBtn; LLButton* mCancelBtn; private: diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 483120c19a..4226316ad4 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -128,30 +128,24 @@ BOOL LLSidepanelTaskInfo::postBuild() childSetCommitCallback("search_check", &LLSidepanelTaskInfo::onCommitIncludeInSearch,this); mDAPermModify = getChild("perm_modify"); - //mDACreator = getChildView("Creator:"); // Doesn't exist as of 2015-11-26 mDACreatorName = getChild("Creator Name"); mDAOwner = getChildView("Owner:"); mDAOwnerName = getChild("Owner Name"); - //mDAGroup = getChildView("Group:"); // Doesn't exist as of 2015-11-26 - //mDAGroupName = getChild("Group Name"); // Doesn't exist as of 2015-11-26 mDAButtonSetGroup = getChildView("button set group"); mDAObjectName = getChild("Object Name"); mDAName = getChildView("Name:"); mDADescription = getChildView("Description:"); mDAObjectDescription = getChild("Object Description"); - //mDAPermissions = getChildView("Permissions:"); // Doesn't exist as of 2015-11-26 mDACheckboxShareWithGroup = getChild("checkbox share with group"); mDAButtonDeed = getChildView("button deed"); mDACheckboxAllowEveryoneMove = getChild("checkbox allow everyone move"); mDACheckboxAllowEveryoneCopy = getChild("checkbox allow everyone copy"); - //mDANextOwnerCan = getChildView("Next owner can:"); // Doesn't exist as of 2015-11-26 mDACheckboxNextOwnerCanModify = getChild("checkbox next owner can modify"); mDACheckboxNextOwnerCanCopy = getChild("checkbox next owner can copy"); mDACheckboxNextOwnerCanTransfer = getChild("checkbox next owner can transfer"); mDACheckboxForSale = getChild("checkbox for sale"); mDASearchCheck = getChild("search_check"); mDAComboSaleType = getChild("sale type"); - //mDACost = getChild("Cost"); // Doesn't exist as of 2015-11-26 mDAEditCost = getChild("Edit Cost"); mDALabelClickAction = getChildView("label click action"); mDAComboClickAction = getChild("clickaction"); @@ -187,7 +181,6 @@ void LLSidepanelTaskInfo::disableAll() mDAPermModify->setEnabled(FALSE); mDAPermModify->setValue(LLStringUtil::null); - //mDACreator->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 mDACreatorName->setValue(LLStringUtil::null); mDACreatorName->setEnabled(FALSE); @@ -195,21 +188,14 @@ void LLSidepanelTaskInfo::disableAll() mDAOwnerName->setValue(LLStringUtil::null); mDAOwnerName->setEnabled(FALSE); - //mDAGroup->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 - //mDAGroupName->setValue(LLStringUtil::null); // Doesn't exist as of 2015-11-26 - //mDAGroupName->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 mDAButtonSetGroup->setEnabled(FALSE); mDAObjectName->setValue(LLStringUtil::null); mDAObjectName->setEnabled(FALSE); mDAName->setEnabled(FALSE); - //mDAGroupName->setValue(LLStringUtil::null); // Doesn't exist as of 2015-11-26 - //mDAGroupName->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 mDADescription->setEnabled(FALSE); mDAObjectDescription->setValue(LLStringUtil::null); mDAObjectDescription->setEnabled(FALSE); - - //mDAPermissions->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 mDACheckboxShareWithGroup->setValue(FALSE); mDACheckboxShareWithGroup->setEnabled(FALSE); @@ -221,7 +207,6 @@ void LLSidepanelTaskInfo::disableAll() mDACheckboxAllowEveryoneCopy->setEnabled(FALSE); //Next owner can: - //mDANextOwnerCan->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 mDACheckboxNextOwnerCanModify->setValue(FALSE); mDACheckboxNextOwnerCanModify->setEnabled(FALSE); mDACheckboxNextOwnerCanCopy->setValue(FALSE); @@ -239,9 +224,7 @@ void LLSidepanelTaskInfo::disableAll() mDAComboSaleType->setValue(LLSaleInfo::FS_COPY); mDAComboSaleType->setEnabled(FALSE); - - //mDACost->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 - //mDACost->setValue(getString("Cost Default")); // Doesn't exist as of 2015-11-26 + mDAEditCost->setValue(LLStringUtil::null); mDAEditCost->setEnabled(FALSE); @@ -369,8 +352,6 @@ void LLSidepanelTaskInfo::refresh() mDAPathfindingAttributes->setEnabled(TRUE); mDAPathfindingAttributes->setValue(LLTrans::getString(pfAttrName)); - - getChildView("Permissions:")->setEnabled(TRUE); // Update creator text field //getChildView("Creator:")->setEnabled(TRUE); // Doesn't exist as of 2015-11-26 @@ -727,7 +708,6 @@ void LLSidepanelTaskInfo::refresh() getChild("checkbox for sale")->setTentative( is_for_sale_mixed); getChildView("sale type")->setEnabled(num_for_sale && can_transfer && !is_sale_price_mixed); - //getChildView("Next owner can:")->setEnabled(TRUE); // Doesn't exist as of 2015-11-26 getChildView("checkbox next owner can modify")->setEnabled(base_mask_on & PERM_MODIFY); getChildView("checkbox next owner can copy")->setEnabled(base_mask_on & PERM_COPY); getChildView("checkbox next owner can transfer")->setEnabled(next_owner_mask_on & PERM_COPY); @@ -737,7 +717,6 @@ void LLSidepanelTaskInfo::refresh() getChildView("checkbox for sale")->setEnabled(FALSE); getChildView("sale type")->setEnabled(FALSE); - //getChildView("Next owner can:")->setEnabled(FALSE); // Doesn't exist as of 2015-11-26 getChildView("checkbox next owner can modify")->setEnabled(FALSE); getChildView("checkbox next owner can copy")->setEnabled(FALSE); getChildView("checkbox next owner can transfer")->setEnabled(FALSE); diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index a385a55335..cbfb07874b 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -125,30 +125,24 @@ private: private: // Pointers cached here to speed up the "disableAll" function which gets called on idle LLUICtrl* mDAPermModify; - //LLView* mDACreator; // Doesn't exist as of 2015-11-26 LLUICtrl* mDACreatorName; LLView* mDAOwner; LLUICtrl* mDAOwnerName; - //LLView* mDAGroup; // Doesn't exist as of 2015-11-26 - //LLUICtrl* mDAGroupName; // Doesn't exist as of 2015-11-26 LLView* mDAButtonSetGroup; LLUICtrl* mDAObjectName; LLView* mDAName; LLView* mDADescription; LLUICtrl* mDAObjectDescription; - //LLView* mDAPermissions; // Doesn't exist as of 2015-11-26 LLUICtrl* mDACheckboxShareWithGroup; LLView* mDAButtonDeed; LLUICtrl* mDACheckboxAllowEveryoneMove; LLUICtrl* mDACheckboxAllowEveryoneCopy; - //LLView* mDANextOwnerCan; // Doesn't exist as of 2015-11-26 LLUICtrl* mDACheckboxNextOwnerCanModify; LLUICtrl* mDACheckboxNextOwnerCanCopy; LLUICtrl* mDACheckboxNextOwnerCanTransfer; LLUICtrl* mDACheckboxForSale; LLUICtrl* mDASearchCheck; LLComboBox* mDAComboSaleType; - //LLUICtrl* mDACost; // Doesn't exist as of 2015-11-26 LLUICtrl* mDAEditCost; LLView* mDALabelClickAction; LLComboBox* mDAComboClickAction; diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 08fbe770d4..fd6853a102 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -87,14 +87,6 @@ - - - diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index a85042a084..4e000b02ea 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -392,6 +392,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="topleft" multi_select="true" name="avatars_online" + keep_one_selected="false" show_permissions_granted="true" width="317" /> @@ -409,6 +410,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="topleft" multi_select="true" name="avatars_all" + keep_one_selected="false" show_permissions_granted="true" width="317" /> @@ -560,6 +562,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M height="388" layout="topleft" left="3" + keep_one_selected="false" name="group_list" right="-2" top_pad="4" /> @@ -670,6 +673,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M multi_select="true" name="avatar_list" show_last_interaction_time="true" + keep_one_selected="false" right="-2" top_pad="4" /> diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index f2aa6bf5ac..618ac8f610 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -131,15 +131,6 @@ width="333"> tab_group="1" top_pad="6" follows="all" /> -