Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion indra/newview/llviewermessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,8 +2250,40 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
if (idRlvRoot.notNull())
mFolderID = idRlvRoot;

std::string expected_name;
std::string::size_type idxToken = mDesc.find("' ( http://");
if (std::string::npos != idxToken && idxToken > 1)
{
expected_name = mDesc.substr(1, idxToken - 1);
}
else
{
std::string::size_type start = mDesc.find('\'');
std::string::size_type end = mDesc.find_last_of('\'');
if ((std::string::npos != start) && (std::string::npos != end) && (end > start + 1))
{
expected_name = mDesc.substr(start + 1, end - start - 1);
}
}
if (expected_name.find(RLV_PUTINV_PREFIX) != 0)
{
expected_name.clear();
}

if (expected_name.empty())
{
std::string::size_type idxPrefix = mDesc.find(RLV_PUTINV_PREFIX);
if (std::string::npos != idxPrefix)
{
std::string::size_type idxEnd = mDesc.find('\'', idxPrefix);
if (std::string::npos == idxEnd)
idxEnd = mDesc.length();
expected_name = mDesc.substr(idxPrefix, idxEnd - idxPrefix);
}
}

// "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder
RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID);
RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID, expected_name);
gInventory.addObserver(pOfferObserver);
}
else
Expand Down
106 changes: 99 additions & 7 deletions indra/newview/rlvinventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llstartup.h"
#include "llviewerfoldertype.h"
#include "llviewermessage.h"
#include "llcallbacklist.h"

#include "rlvinventory.h"

Expand Down Expand Up @@ -603,17 +604,59 @@ void RlvGiveToRLVOffer::moveAndRename(const LLUUID& idFolder, const LLUUID& idDe

void RlvGiveToRLVTaskOffer::changed(U32 mask)
{
if ( (mask & LLInventoryObserver::ADD) && (gInventory.getTransactionId().notNull()) && (m_idTransaction == gInventory.getTransactionId()) )
{ // BulkUpdateInventory
const auto& idItems = gInventory.getAddedIDs();
for (const LLUUID& idItem : idItems)
if (!(mask & LLInventoryObserver::ADD))
{
return;
}

const LLUUID& transaction_id = gInventory.getTransactionId();
if (transaction_id.notNull() && (m_idTransaction != transaction_id))
{
// Some inventory updates report a different transaction id (or reuse one).
// If we have an exact expected name, allow a fallback match; otherwise bail.
if (m_strExpectedName.empty())
{
return;
}
}

const LLUUID id_rlv_root = RlvInventory::instance().getSharedRootID();
bool found_folder = false;
const auto& idItems = gInventory.getAddedIDs();
for (const LLUUID& idItem : idItems)
{
LLInventoryCategory* pCategory = gInventory.getCategory(idItem);
if (!pCategory)
{
continue;
}

if (!m_strExpectedName.empty())
{
if (LLInventoryCategory* pCategory = gInventory.getCategory(idItem))
if (pCategory->getName() != m_strExpectedName)
{
continue;
}

if (id_rlv_root.notNull() && !gInventory.isObjectDescendentOf(pCategory->getUUID(), id_rlv_root))
{
if (std::find(m_Folders.begin(), m_Folders.end(), pCategory->getUUID()) == m_Folders.end())
m_Folders.push_back(pCategory->getUUID());
continue;
}
}
else if (pCategory->getName().find(RLV_PUTINV_PREFIX) != 0)
{
continue;
}

if (std::find(m_Folders.begin(), m_Folders.end(), pCategory->getUUID()) == m_Folders.end())
{
m_Folders.push_back(pCategory->getUUID());
found_folder = true;
}
}

if (!m_Folders.empty())
{
done();
}
}
Expand All @@ -637,6 +680,8 @@ void RlvGiveToRLVTaskOffer::onDestinationCreated(const LLUUID& idDestFolder, con
{
if (idDestFolder.notNull())
{
m_idExpectedParent = idDestFolder;
m_strExpectedLeaf = strName;
moveAndRename(m_Folders.front(), idDestFolder, strName, new LLBoostFuncInventoryCallback(boost::bind(&RlvGiveToRLVTaskOffer::onOfferCompleted, this, _1)));
}
else
Expand All @@ -650,7 +695,54 @@ void RlvGiveToRLVTaskOffer::onOfferCompleted(const LLUUID& idOfferedFolder)
if (idOfferedFolder.notNull())
{
RlvBehaviourNotifyHandler::sendNotification("accepted_in_rlv inv_offer " + RlvInventory::instance().getSharedPath(idOfferedFolder));

// AIS can apply the initial folder update after our rename, causing the
// full path name to reappear or the folder to land in #RLV. Retry a few times.
const LLUUID expected_parent = m_idExpectedParent;
const std::string expected_leaf = m_strExpectedLeaf;
auto schedule_retry = [idOfferedFolder, expected_parent, expected_leaf](F32 delay)
{
doAfterInterval([idOfferedFolder, expected_parent, expected_leaf]()
{
LLViewerInventoryCategory* pFolder = gInventory.getCategory(idOfferedFolder);
if (!pFolder)
{
return;
}

const std::string& cur_name = pFolder->getName();
const bool needs_move = expected_parent.notNull() && (pFolder->getParentUUID() != expected_parent);
const bool needs_rename = !expected_leaf.empty() && (cur_name != expected_leaf);

if (!needs_move && !needs_rename)
{
return;
}

if (needs_move)
{
gInventory.changeCategoryParent(pFolder, expected_parent, false);
gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, idOfferedFolder);
gInventory.notifyObservers();
gInventory.fetchDescendentsOf(expected_parent);
}

if (needs_rename)
{
rename_category(&gInventory, idOfferedFolder, expected_leaf, nullptr);
if (expected_parent.notNull())
{
gInventory.fetchDescendentsOf(expected_parent);
}
}
}, delay);
};

schedule_retry(1.0f);
schedule_retry(5.0f);
schedule_retry(10.0f);
}

delete this;
}

Expand Down
11 changes: 10 additions & 1 deletion indra/newview/rlvinventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,13 @@ class RlvGiveToRLVOffer
class RlvGiveToRLVTaskOffer : public LLInventoryObserver, RlvGiveToRLVOffer
{
public:
RlvGiveToRLVTaskOffer(const LLUUID& idTransaction) : RlvGiveToRLVOffer(), m_idTransaction(idTransaction) {}
RlvGiveToRLVTaskOffer(const LLUUID& idTransaction, const std::string& expected_name)
: RlvGiveToRLVOffer(),
m_idTransaction(idTransaction),
m_strExpectedName(expected_name),
m_idExpectedParent(LLUUID::null),
m_strExpectedLeaf()
{}
void changed(U32 mask) override;
protected:
void done();
Expand All @@ -157,6 +163,9 @@ class RlvGiveToRLVTaskOffer : public LLInventoryObserver, RlvGiveToRLVOffer
typedef std::vector<LLUUID> folder_ref_t;
folder_ref_t m_Folders;
LLUUID m_idTransaction;
std::string m_strExpectedName;
LLUUID m_idExpectedParent;
std::string m_strExpectedLeaf;
};

class RlvGiveToRLVAgentOffer : public LLInventoryFetchDescendentsObserver, RlvGiveToRLVOffer
Expand Down