Merge viewer-neko
commit
46fb5a7648
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<LLXfer*> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<LLXfer *> xfer_list_t;
|
||||
xfer_list_t mSendList;
|
||||
xfer_list_t mReceiveList;
|
||||
|
||||
typedef std::list<LLHostStatus*> 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<std::string> mExpectedTransfers; // files that are authorized to transfer out
|
||||
std::multiset<std::string> 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;
|
||||
|
|
|
|||
|
|
@ -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<LLInventoryCallback>(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<LLInventoryCallback>(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<LLInventoryObject>(item));
|
||||
link_inventory_array(parent_id,
|
||||
obj_array,
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
else if (LLAssetType::lookupIsLinkType(item->getActualType()))
|
||||
{
|
||||
LLInventoryObject::const_object_list_t obj_array;
|
||||
obj_array.push_back(LLConstPointer<LLInventoryObject>(item));
|
||||
link_inventory_array(parent_id,
|
||||
obj_array,
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
// [/SL:KB]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,10 +434,11 @@ void copy_inventory_category(LLInventoryModel* model,
|
|||
LLInventoryItem* item = *iter;
|
||||
LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, new_cat_uuid));
|
||||
|
||||
// <FS:Ansariel> 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()))
|
||||
// </FS:Ansariel>
|
||||
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);
|
||||
}
|
||||
// <FS:Ansariel> FIRE-21719: Copy-pasting a folder doesn't copy contained links
|
||||
else if (item->getIsLinkType())
|
||||
{
|
||||
link_inventory_object(new_cat_uuid, item->getLinkedUUID(), cb);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
else
|
||||
{
|
||||
copy_inventory_item(
|
||||
|
|
|
|||
|
|
@ -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<LODRequest> 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<LODRequest>::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<HeaderRequest> 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<LLUUID> incomplete;
|
||||
std::set<LLUUID>::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<HeaderRequest>::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<UUIDBasedRequest> incomplete;
|
||||
while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
|
||||
{
|
||||
mMutex->lock();
|
||||
std::set<UUIDBasedRequest>::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<LLUUID> incomplete;
|
||||
std::set<LLUUID>::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<UUIDBasedRequest> incomplete;
|
||||
while (!mDecompositionRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
|
||||
{
|
||||
mMutex->lock();
|
||||
std::set<UUIDBasedRequest>::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<LLUUID> incomplete;
|
||||
std::set<LLUUID>::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<UUIDBasedRequest> incomplete;
|
||||
while (!mPhysicsShapeRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
|
||||
{
|
||||
mMutex->lock();
|
||||
std::set<UUIDBasedRequest>::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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<LLUUID, U32> 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<LLUUID> mSkinRequests;
|
||||
std::set<UUIDBasedRequest> mSkinRequests;
|
||||
|
||||
// list of completed skin info requests
|
||||
std::list<LLMeshSkinInfo> mSkinInfoQ;
|
||||
|
||||
//set of requested decompositions
|
||||
std::set<LLUUID> mDecompositionRequests;
|
||||
std::set<UUIDBasedRequest> mDecompositionRequests;
|
||||
|
||||
//set of requested physics shapes
|
||||
std::set<LLUUID> mPhysicsShapeRequests;
|
||||
std::set<UUIDBasedRequest> mPhysicsShapeRequests;
|
||||
|
||||
// list of completed Decomposition info requests
|
||||
std::list<LLModel::Decomposition*> 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);
|
||||
|
|
|
|||
|
|
@ -215,16 +215,6 @@ BOOL LLPanelGroup::postBuild()
|
|||
button = getChild<LLButton>("btn_chat");
|
||||
button->setClickedCallback(onBtnGroupChatClicked, this);
|
||||
|
||||
// <FS:Ansariel> Might not exist
|
||||
//button = getChild<LLButton>("btn_cancel");
|
||||
//button->setVisible(false); button->setEnabled(true);
|
||||
button = findChild<LLButton>("btn_cancel");
|
||||
if (button)
|
||||
{
|
||||
button->setVisible(false); button->setEnabled(true);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
button = getChild<LLButton>("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<LLPanelGroupTab>("group_general_tab_panel");
|
||||
LLPanelGroupTab* panel_roles = findChild<LLPanelGroupTab>("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<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ protected:
|
|||
void onBtnCreate();
|
||||
void onBackBtnClick();
|
||||
void onBtnJoin();
|
||||
void onBtnCancel();
|
||||
|
||||
static void onBtnApply(void*);
|
||||
static void onBtnRefresh(void*);
|
||||
|
|
|
|||
|
|
@ -479,20 +479,12 @@ BOOL LLPanelGroupSubTab::postBuild()
|
|||
{
|
||||
// Hook up the search widgets.
|
||||
bool recurse = true;
|
||||
// <FS:Ansariel> Does not exist on all tabs!
|
||||
//mSearchEditor = getChild<LLFilterEditor>("filter_input", recurse);
|
||||
|
||||
//if (!mSearchEditor)
|
||||
// return FALSE;
|
||||
|
||||
//mSearchEditor->setCommitCallback(boost::bind(&LLPanelGroupSubTab::setSearchFilter, this, _2));
|
||||
mSearchEditor = findChild<LLFilterEditor>("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));
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
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;
|
||||
// <FS:Ansariel> Might not exist
|
||||
//mHeader = parent->getChild<LLPanel>("members_header", recurse);
|
||||
//mFooter = parent->getChild<LLPanel>("members_footer", recurse);
|
||||
mHeader = parent->findChild<LLPanel>("members_header", recurse);
|
||||
mFooter = parent->findChild<LLPanel>("members_footer", recurse);
|
||||
// </FS:Ansariel>
|
||||
|
||||
mMembersList = parent->getChild<LLNameListCtrl>("member_list", recurse);
|
||||
mAssignedRolesList = parent->getChild<LLScrollListCtrl>("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;
|
||||
// <FS:Ansariel> Might not exist
|
||||
//mHeader = parent->getChild<LLPanel>("roles_header", recurse);
|
||||
//mFooter = parent->getChild<LLPanel>("roles_footer", recurse);
|
||||
mHeader = parent->findChild<LLPanel>("roles_header", recurse);
|
||||
mFooter = parent->findChild<LLPanel>("roles_footer", recurse);
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
||||
mRolesList = parent->getChild<LLScrollListCtrl>("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;
|
||||
// <FS:Ansariel> Might not exist
|
||||
//mHeader = parent->getChild<LLPanel>("actions_header", recurse);
|
||||
//mFooter = parent->getChild<LLPanel>("actions_footer", recurse);
|
||||
mHeader = parent->findChild<LLPanel>("actions_header", recurse);
|
||||
mFooter = parent->findChild<LLPanel>("actions_footer", recurse);
|
||||
// </FS:Ansariel>
|
||||
|
||||
mActionDescription = parent->getChild<LLTextEditor>("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;
|
||||
|
||||
// <FS:Ansariel> Might not exist
|
||||
//mHeader = parent->getChild<LLPanel>("banlist_header", recurse);
|
||||
//mFooter = parent->getChild<LLPanel>("banlist_footer", recurse);
|
||||
mHeader = parent->findChild<LLPanel>("banlist_header", recurse);
|
||||
mFooter = parent->findChild<LLPanel>("banlist_footer", recurse);
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
||||
mHeader = parent->findChild<LLPanel>("banlist_header", recurse);
|
||||
mFooter = parent->findChild<LLPanel>("banlist_footer", recurse);
|
||||
|
||||
mBanList = parent->getChild<LLNameListCtrl>("ban_list", recurse);
|
||||
|
||||
mCreateBanButton = parent->getChild<LLButton>("ban_create", recurse);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; // <FS:ND/> 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;
|
||||
// <FS:AW opensim currency support>
|
||||
// info << LLTrans::getString("BuyforL$") << price;
|
||||
info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price;
|
||||
// </FS:AW opensim currency support>
|
||||
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<LLMenuItemCallGL*>(*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;
|
||||
// <FS:AW opensim currency support>
|
||||
// info << LLTrans::getString("BuyforL$") << price;
|
||||
info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price;
|
||||
// </FS:AW opensim currency support>
|
||||
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<LLMenuItemCallGL*>(*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;
|
||||
// <FS:AW opensim currency support>
|
||||
// info << LLTrans::getString("BuyforL$") << price;
|
||||
info << Tea::wrapCurrency(LLTrans::getString("BuyforL$")) << price;
|
||||
// </FS:AW opensim currency support>
|
||||
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<LLMenuItemCallGL*>(*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"));
|
||||
// <FS:Ansariel> Legacy object properties
|
||||
//if ((flags & FIRST_SELECTED_ITEM) == 0)
|
||||
|
|
|
|||
|
|
@ -538,13 +538,6 @@ BOOL LLPanelOutfitEdit::postBuild()
|
|||
|
||||
mPlusBtn = getChild<LLButton>("plus_btn");
|
||||
mPlusBtn->setClickedCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
|
||||
|
||||
// <FS:Ansariel> Unused as of 06-12-2017
|
||||
//mEditWearableBtn = getChild<LLButton>("edit_wearable_btn");
|
||||
//mEditWearableBtn->setEnabled(FALSE);
|
||||
//mEditWearableBtn->setVisible(FALSE);
|
||||
//mEditWearableBtn->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this));
|
||||
// </FS:Ansariel>
|
||||
|
||||
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
|
||||
|
||||
|
|
|
|||
|
|
@ -217,7 +217,6 @@ private:
|
|||
LLFilterEditor* mSearchFilter;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
std::string mSearchString;
|
||||
//LLButton* mEditWearableBtn; // <FS:Ansariel> Unused as of 06-12-2017
|
||||
LLButton* mFolderViewBtn;
|
||||
LLButton* mListViewBtn;
|
||||
LLButton* mPlusBtn;
|
||||
|
|
|
|||
|
|
@ -208,7 +208,9 @@ BOOL LLPanelPermissions::postBuild()
|
|||
childSetCommitCallback("clickaction",LLPanelPermissions::onCommitClickAction,this);
|
||||
childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this);
|
||||
|
||||
// mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
|
||||
//mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
|
||||
//mLabelOwnerName = getChild<LLTextBox>("Owner Name");
|
||||
//mLabelCreatorName = getChild<LLTextBox>("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<LLUICtrl>("Creator Icon")->setVisible(FALSE);
|
||||
//mLabelCreatorName->setValue(LLStringUtil::null);
|
||||
//mLabelCreatorName->setEnabled(FALSE);
|
||||
getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null);
|
||||
getChildView("Creator Name")->setEnabled(FALSE);
|
||||
|
||||
getChildView("Owner:")->setEnabled(FALSE);
|
||||
//getChild<LLUICtrl>("Owner Icon")->setVisible(FALSE);
|
||||
//getChild<LLUICtrl>("Owner Group Icon")->setVisible(FALSE);
|
||||
//mLabelOwnerName->setValue(LLStringUtil::null);
|
||||
//mLabelOwnerName->setEnabled(FALSE);
|
||||
getChild<LLUICtrl>("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<LLTextBox>("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<LLTextBox>("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<LLAvatarIconCtrl>("Creator Icon")->setValue(mCreatorID);
|
||||
// getChild<LLAvatarIconCtrl>("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<LLTextBox>("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<LLGroupIconCtrl>("Owner Group Icon")->setIconId(group_data->mInsigniaID);
|
||||
// getChild<LLGroupIconCtrl>("Owner Group Icon")->setVisible(TRUE);
|
||||
// getChild<LLUICtrl>("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<LLTextBox>("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<LLAvatarIconCtrl>("Owner Icon")->setValue(owner_id);
|
||||
// getChild<LLAvatarIconCtrl>("Owner Icon")->setVisible(TRUE);
|
||||
// getChild<LLUICtrl>("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*)
|
||||
|
|
|
|||
|
|
@ -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<LLViewerObject> mLastSelectedObject;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -104,12 +104,6 @@ BOOL LLSidepanelAppearance::postBuild()
|
|||
|
||||
childSetAction("edit_outfit_btn", boost::bind(&LLSidepanelAppearance::showOutfitEditPanel, this));
|
||||
|
||||
// <FS:Ansariel> Disabled as of 12-09-2014
|
||||
//mNewOutfitBtn = getChild<LLButton>("newlook_btn");
|
||||
//mNewOutfitBtn->setClickedCallback(boost::bind(&LLSidepanelAppearance::onNewOutfitButtonClicked, this));
|
||||
//mNewOutfitBtn->setEnabled(false);
|
||||
// </FS:Ansariel>
|
||||
|
||||
mFilterEditor = getChild<LLFilterEditor>("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); // <FS:Ansariel> 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); // <FS:Ansariel> 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); // <FS:Ansariel> Disabled as of 12-09-2014
|
||||
}
|
||||
|
||||
void LLSidepanelAppearance::setWearablesLoading(bool val)
|
||||
|
|
|
|||
|
|
@ -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; // <FS:Ansariel> Disabled as of 12-09-2014
|
||||
LLPanel* mCurrOutfitPanel;
|
||||
|
||||
LLTextBox* mCurrentLookName;
|
||||
|
|
|
|||
|
|
@ -193,11 +193,6 @@ BOOL LLSidepanelInventory::postBuild()
|
|||
mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn");
|
||||
mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this));
|
||||
|
||||
// <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
|
||||
//mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
|
||||
// </FS:Ansariel>
|
||||
|
||||
mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
|
||||
mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
|
||||
LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
|
||||
|
|
@ -570,12 +565,6 @@ void LLSidepanelInventory::onTeleportButtonClicked()
|
|||
performActionOnSelection("teleport");
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//void LLSidepanelInventory::onOverflowButtonClicked()
|
||||
//{
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLSidepanelInventory::onBackButtonClicked()
|
||||
{
|
||||
showInventoryPanel();
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ protected:
|
|||
void onWearButtonClicked();
|
||||
void onPlayButtonClicked();
|
||||
void onTeleportButtonClicked();
|
||||
//void onOverflowButtonClicked(); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
public:
|
||||
void onBackButtonClicked();
|
||||
|
||||
|
|
@ -127,7 +126,6 @@ private:
|
|||
LLButton* mWearBtn;
|
||||
LLButton* mPlayBtn;
|
||||
LLButton* mTeleportBtn;
|
||||
//LLButton* mOverflowBtn; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLButton* mShopBtn;
|
||||
|
||||
bool mInboxEnabled;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
// <FS:Ansariel> Doesn't exist on every sub panel
|
||||
//mSaveBtn = getChild<LLButton>("save_btn");
|
||||
//mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this));
|
||||
|
||||
//mCancelBtn = getChild<LLButton>("cancel_btn");
|
||||
//mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this));
|
||||
mSaveBtn = findChild<LLButton>("save_btn");
|
||||
if (mSaveBtn)
|
||||
{
|
||||
mSaveBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onSaveButtonClicked, this));
|
||||
}
|
||||
|
||||
mCancelBtn = findChild<LLButton>("cancel_btn");
|
||||
if (mCancelBtn)
|
||||
{
|
||||
mCancelBtn->setClickedCallback(boost::bind(&LLSidepanelInventorySubpanel::onCancelButtonClicked, this));
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -131,18 +117,10 @@ void LLSidepanelInventorySubpanel::dirty()
|
|||
|
||||
void LLSidepanelInventorySubpanel::updateVerbs()
|
||||
{
|
||||
// <FS:Ansariel> Doesn't exist on every sub panel
|
||||
//mSaveBtn->setVisible(mIsEditing);
|
||||
//mCancelBtn->setVisible(mIsEditing);
|
||||
if (mSaveBtn)
|
||||
{
|
||||
mSaveBtn->setVisible(mIsEditing);
|
||||
}
|
||||
if (mCancelBtn)
|
||||
{
|
||||
mCancelBtn->setVisible(mIsEditing);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
void LLSidepanelInventorySubpanel::onEditButtonClicked()
|
||||
|
|
@ -152,14 +130,6 @@ void LLSidepanelInventorySubpanel::onEditButtonClicked()
|
|||
updateVerbs();
|
||||
}
|
||||
|
||||
void LLSidepanelInventorySubpanel::onSaveButtonClicked()
|
||||
{
|
||||
save();
|
||||
setIsEditing(FALSE);
|
||||
refresh();
|
||||
updateVerbs();
|
||||
}
|
||||
|
||||
void LLSidepanelInventorySubpanel::onCancelButtonClicked()
|
||||
{
|
||||
setIsEditing(FALSE);
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@ protected:
|
|||
//
|
||||
protected:
|
||||
void onEditButtonClicked();
|
||||
void onSaveButtonClicked();
|
||||
void onCancelButtonClicked();
|
||||
LLButton* mSaveBtn;
|
||||
LLButton* mCancelBtn;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -128,30 +128,24 @@ BOOL LLSidepanelTaskInfo::postBuild()
|
|||
childSetCommitCallback("search_check", &LLSidepanelTaskInfo::onCommitIncludeInSearch,this);
|
||||
|
||||
mDAPermModify = getChild<LLUICtrl>("perm_modify");
|
||||
//mDACreator = getChildView("Creator:"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDACreatorName = getChild<LLUICtrl>("Creator Name");
|
||||
mDAOwner = getChildView("Owner:");
|
||||
mDAOwnerName = getChild<LLUICtrl>("Owner Name");
|
||||
//mDAGroup = getChildView("Group:"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mDAGroupName = getChild<LLUICtrl>("Group Name"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDAButtonSetGroup = getChildView("button set group");
|
||||
mDAObjectName = getChild<LLUICtrl>("Object Name");
|
||||
mDAName = getChildView("Name:");
|
||||
mDADescription = getChildView("Description:");
|
||||
mDAObjectDescription = getChild<LLUICtrl>("Object Description");
|
||||
//mDAPermissions = getChildView("Permissions:"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDACheckboxShareWithGroup = getChild<LLUICtrl>("checkbox share with group");
|
||||
mDAButtonDeed = getChildView("button deed");
|
||||
mDACheckboxAllowEveryoneMove = getChild<LLUICtrl>("checkbox allow everyone move");
|
||||
mDACheckboxAllowEveryoneCopy = getChild<LLUICtrl>("checkbox allow everyone copy");
|
||||
//mDANextOwnerCan = getChildView("Next owner can:"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDACheckboxNextOwnerCanModify = getChild<LLUICtrl>("checkbox next owner can modify");
|
||||
mDACheckboxNextOwnerCanCopy = getChild<LLUICtrl>("checkbox next owner can copy");
|
||||
mDACheckboxNextOwnerCanTransfer = getChild<LLUICtrl>("checkbox next owner can transfer");
|
||||
mDACheckboxForSale = getChild<LLUICtrl>("checkbox for sale");
|
||||
mDASearchCheck = getChild<LLUICtrl>("search_check");
|
||||
mDAComboSaleType = getChild<LLComboBox>("sale type");
|
||||
//mDACost = getChild<LLUICtrl>("Cost"); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDAEditCost = getChild<LLUICtrl>("Edit Cost");
|
||||
mDALabelClickAction = getChildView("label click action");
|
||||
mDAComboClickAction = getChild<LLComboBox>("clickaction");
|
||||
|
|
@ -187,7 +181,6 @@ void LLSidepanelTaskInfo::disableAll()
|
|||
mDAPermModify->setEnabled(FALSE);
|
||||
mDAPermModify->setValue(LLStringUtil::null);
|
||||
|
||||
//mDACreator->setEnabled(FALSE); // <FS:Ansariel> 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); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mDAGroupName->setValue(LLStringUtil::null); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mDAGroupName->setEnabled(FALSE); // <FS:Ansariel> 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); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mDAGroupName->setEnabled(FALSE); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
mDADescription->setEnabled(FALSE);
|
||||
mDAObjectDescription->setValue(LLStringUtil::null);
|
||||
mDAObjectDescription->setEnabled(FALSE);
|
||||
|
||||
//mDAPermissions->setEnabled(FALSE); // <FS:Ansariel> 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); // <FS:Ansariel> 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); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//mDACost->setValue(getString("Cost Default")); // <FS:Ansariel> 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); // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
|
|
@ -727,7 +708,6 @@ void LLSidepanelTaskInfo::refresh()
|
|||
getChild<LLUICtrl>("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); // <FS:Ansariel> 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); // <FS:Ansariel> 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);
|
||||
|
|
|
|||
|
|
@ -125,30 +125,24 @@ private:
|
|||
private:
|
||||
// Pointers cached here to speed up the "disableAll" function which gets called on idle
|
||||
LLUICtrl* mDAPermModify;
|
||||
//LLView* mDACreator; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLUICtrl* mDACreatorName;
|
||||
LLView* mDAOwner;
|
||||
LLUICtrl* mDAOwnerName;
|
||||
//LLView* mDAGroup; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
//LLUICtrl* mDAGroupName; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLView* mDAButtonSetGroup;
|
||||
LLUICtrl* mDAObjectName;
|
||||
LLView* mDAName;
|
||||
LLView* mDADescription;
|
||||
LLUICtrl* mDAObjectDescription;
|
||||
//LLView* mDAPermissions; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLUICtrl* mDACheckboxShareWithGroup;
|
||||
LLView* mDAButtonDeed;
|
||||
LLUICtrl* mDACheckboxAllowEveryoneMove;
|
||||
LLUICtrl* mDACheckboxAllowEveryoneCopy;
|
||||
//LLView* mDANextOwnerCan; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLUICtrl* mDACheckboxNextOwnerCanModify;
|
||||
LLUICtrl* mDACheckboxNextOwnerCanCopy;
|
||||
LLUICtrl* mDACheckboxNextOwnerCanTransfer;
|
||||
LLUICtrl* mDACheckboxForSale;
|
||||
LLUICtrl* mDASearchCheck;
|
||||
LLComboBox* mDAComboSaleType;
|
||||
//LLUICtrl* mDACost; // <FS:Ansariel> Doesn't exist as of 2015-11-26
|
||||
LLUICtrl* mDAEditCost;
|
||||
LLView* mDALabelClickAction;
|
||||
LLComboBox* mDAComboClickAction;
|
||||
|
|
|
|||
|
|
@ -87,14 +87,6 @@
|
|||
<menu_item_call.on_click
|
||||
function="Inventory.Share" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Buy"
|
||||
layout="topleft"
|
||||
name="Task Buy">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="task_buy" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open"
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@
|
|||
layout="topleft"
|
||||
left="3"
|
||||
name="blocked"
|
||||
keep_one_selected="false"
|
||||
tool_tip="List of currently blocked Residents"
|
||||
top_pad="4"
|
||||
right="-1"/>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
</panel>
|
||||
|
|
@ -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" />
|
||||
</panel>
|
||||
|
|
@ -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" />
|
||||
</panel>
|
||||
|
|
|
|||
|
|
@ -131,15 +131,6 @@ width="333">
|
|||
tab_group="1"
|
||||
top_pad="6"
|
||||
follows="all" />
|
||||
<!-- <button
|
||||
follows="bottom|left"
|
||||
height="23"
|
||||
label="New outfit"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
right="-10"
|
||||
name="newlook_btn"
|
||||
width="100" />-->
|
||||
<panel
|
||||
class="panel_outfit_edit"
|
||||
filename="panel_outfit_edit.xml"
|
||||
|
|
|
|||
Loading…
Reference in New Issue