Merge viewer-neko

master
Ansariel 2018-05-09 23:03:43 +02:00
commit 46fb5a7648
35 changed files with 784 additions and 851 deletions

View File

@ -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;
}

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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]
}
}

View File

@ -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(

View File

@ -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
{

View File

@ -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);

View File

@ -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)

View File

@ -100,7 +100,6 @@ protected:
void onBtnCreate();
void onBackBtnClick();
void onBtnJoin();
void onBtnCancel();
static void onBtnApply(void*);
static void onBtnRefresh(void*);

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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()));

View File

@ -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;

View File

@ -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*)

View File

@ -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;
};

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -62,9 +62,7 @@ protected:
//
protected:
void onEditButtonClicked();
void onSaveButtonClicked();
void onCancelButtonClicked();
LLButton* mSaveBtn;
LLButton* mCancelBtn;
private:

View File

@ -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);

View File

@ -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;

View File

@ -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"

View File

@ -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"/>

View File

@ -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>

View File

@ -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"