Aaaand more, this time for llagentwearables.cpp

This commit is contained in:
Lirusaito
2016-05-26 11:51:49 -04:00
parent a388ddb0d0
commit 4bfd4b38bc
3 changed files with 91 additions and 551 deletions

View File

@@ -49,7 +49,7 @@
#include "lltooldraganddrop.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
#include "llwearable.h"
#include "llviewerwearable.h"
#include "llwearablelist.h"
#include "lllocaltextureobject.h"
@@ -71,6 +71,9 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
bool LLAgentWearables::mInitialWearablesLoaded = false;
// [/SL:KB]
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
bool LLAgentWearables::mInitialAttachmentsRequested = false;
// [/RLVa:KB]
using namespace LLAvatarAppearanceDefines;
@@ -175,13 +178,6 @@ void LLAgentWearables::dump()
}
}
LL_INFOS() << "Total items awaiting wearable update " << mItemsAwaitingWearableUpdate.size() << LL_ENDL;
for (std::set<LLUUID>::iterator it = mItemsAwaitingWearableUpdate.begin();
it != mItemsAwaitingWearableUpdate.end();
++it)
{
LL_INFOS() << (*it).asString() << LL_ENDL;
}
}
struct LLAgentDumper
@@ -236,7 +232,11 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
if(!gHippoGridManager->getConnectedGrid()->isSecondLife())
{
avatar->outputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
gAgent.sendReliableMessage();
}
setAvatarAppearance(avatar);
}
@@ -271,15 +271,6 @@ void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& i
gAgentWearables.addWearabletoAgentInventoryDone(mType, mIndex, inv_item, mWearable);
if (mTodo & CALL_UPDATE)
{
gAgentWearables.sendAgentWearablesUpdate();
}
if (mTodo & CALL_RECOVERDONE)
{
LLAppearanceMgr::instance().addCOFItemLink(inv_item);
gAgentWearables.recoverMissingWearableDone();
}
/*
* Do this for every one in the loop
*/
@@ -337,81 +328,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
gInventory.notifyObservers();
}
void LLAgentWearables::sendAgentWearablesUpdate()
{
// First make sure that we have inventory items for each wearable
for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
{
for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
{
LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);
if (wearable)
{
if (wearable->getItemID().isNull())
{
LLPointer<LLInventoryCallback> cb =
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
(LLWearableType::EType)type,
index,
wearable,
AddWearableToAgentInventoryCallback::CALL_NONE);
addWearableToAgentInventory(cb, wearable);
}
else
{
gInventory.addChangedMask( LLInventoryObserver::LABEL,
wearable->getItemID());
}
}
}
}
// Then make sure the inventory is in sync with the avatar.
gInventory.notifyObservers();
// Send the AgentIsNowWearing
gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
LL_DEBUGS() << "sendAgentWearablesUpdate()" << LL_ENDL;
// MULTI-WEARABLE: DEPRECATED: HACK: index to 0- server database tables don't support concept of multiwearables.
for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
{
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
U8 type_u8 = (U8)type;
gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 );
LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);
if( wearable )
{
//LL_INFOS() << "Sending wearable " << wearable->getName() << LL_ENDL;
LLUUID item_id = wearable->getItemID();
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item && item->getIsLinkType())
{
// Get the itemID that this item points to. i.e. make sure
// we are storing baseitems, not their links, in the database.
item_id = item->getLinkedUUID();
}
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
}
else
{
//LL_INFOS() << "Not wearing wearable type " << LLWearableType::getTypeName((LLWearableType::EType)i) << LL_ENDL;
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null);
}
LL_DEBUGS() << " " << LLWearableType::getTypeLabel((LLWearableType::EType)type) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << LL_ENDL;
}
gAgent.sendReliableMessage();
}
void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index,
const std::string new_name)
{
LLViewerWearable* old_wearable = getViewerWearable(type, index);
@@ -458,10 +375,6 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
{
// Add a new inventory item (shouldn't ever happen here)
U32 todo = AddWearableToAgentInventoryCallback::CALL_NONE;
if (send_update)
{
todo |= AddWearableToAgentInventoryCallback::CALL_UPDATE;
}
LLPointer<LLInventoryCallback> cb =
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
@@ -474,11 +387,6 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
}
gAgentAvatarp->wearableUpdated( type, TRUE );
if( send_update )
{
sendAgentWearablesUpdate();
}
}
}
@@ -491,20 +399,20 @@ LLViewerWearable* LLAgentWearables::saveWearableAs(const LLWearableType::EType t
if (!isWearableCopyable(type, index))
{
LL_WARNS() << "LLAgent::saveWearableAs() not copyable." << LL_ENDL;
return NULL;
return nullptr;
}
LLViewerWearable* old_wearable = getViewerWearable(type, index);
if (!old_wearable)
{
LL_WARNS() << "LLAgent::saveWearableAs() no old wearable." << LL_ENDL;
return NULL;
return nullptr;
}
LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index));
if (!item)
{
LL_WARNS() << "LLAgent::saveWearableAs() no inventory item." << LL_ENDL;
return NULL;
return nullptr;
}
std::string trunc_name(new_name);
LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
@@ -573,9 +481,8 @@ void LLAgentWearables::saveAllWearables()
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
saveWearable((LLWearableType::EType)i, j, FALSE);
saveWearable((LLWearableType::EType)i, j);
}
sendAgentWearablesUpdate();
}
// Called when the user changes the name of a wearable inventory item that is currently being worn.
@@ -604,7 +511,6 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
old_wearable->setName(old_name);
setWearable((LLWearableType::EType)i,j,new_wearable);
sendAgentWearablesUpdate();
break;
}
}
@@ -752,15 +658,6 @@ LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_i
return NULL;
}
void LLAgentWearables::sendAgentWearablesRequest()
{
gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
gAgent.sendReliableMessage();
}
LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)
{
return dynamic_cast<LLViewerWearable*> (getWearable(type, index));
@@ -819,18 +716,6 @@ void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
}
}
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
{
return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
}
U32 LLAgentWearables::itemUpdatePendingCount() const
{
return mItemsAwaitingWearableUpdate.size();
}
const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
{
const LLViewerWearable *wearable = getViewerWearable(type,index);
@@ -882,159 +767,6 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const
return getWearableFromItemID(item_id) != NULL;
}
// MULTI-WEARABLE: DEPRECATED (see backwards compatibility)
// static
// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
// that viewers have a Current Outfit Folder and won't need this message, and thus
// we can remove/ignore this whole function. EXCEPT gAgentWearables.notifyLoadingStarted
void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
{
// We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates
// that may result from AgentWearablesRequest having been sent more than once.
if (mInitialWearablesUpdateReceived)
return;
if (isAgentAvatarValid())
{
//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading.
gAgentAvatarp->startPhase("process_initial_wearables_update");
gAgentAvatarp->outputRezTiming("Received initial wearables update");
}
// notify subscribers that wearables started loading. See EXT-7777
// *TODO: find more proper place to not be called from deprecated method.
// Seems such place is found: LLInitialWearablesFetch::processContents()
gAgentWearables.notifyLoadingStarted();
mInitialWearablesUpdateReceived = true;
LLUUID agent_id;
gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
if (isAgentAvatarValid() && (agent_id == gAgentAvatarp->getID()))
{
gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgentQueryManager.mUpdateSerialNum);
const S32 NUM_BODY_PARTS = 4;
S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData);
if (num_wearables < NUM_BODY_PARTS)
{
// Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin).
// The fact that they don't have any here (only a dummy is sent) implies that either:
// 1. This account existed before we had wearables
// 2. The database has gotten messed up
// 3. This is the account's first login (i.e. the wearables haven't been generated yet).
return;
}
// Get the UUID of the current outfit folder (will be created if it doesn't exist)
const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch(current_outfit_id);
//LL_DEBUGS() << "processAgentInitialWearablesUpdate()" << LL_ENDL;
// Add wearables
// MULTI-WEARABLE: DEPRECATED: Message only supports one wearable per type, will be ignored in future.
gAgentWearables.mItemsAwaitingWearableUpdate.clear();
for (S32 i=0; i < num_wearables; i++)
{
// Parse initial wearables data from message system
U8 type_u8 = 0;
gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i);
if (type_u8 >= LLWearableType::WT_COUNT)
{
continue;
}
LLWearableType::EType type = (LLWearableType::EType) type_u8;
LLUUID item_id;
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i );
LLUUID asset_id;
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i );
if( asset_id.isNull() )
{
LLViewerWearable::removeFromAvatar( type, FALSE );
}
else
{
LLAssetType::EType asset_type = LLWearableType::getAssetType( type );
if (asset_type == LLAssetType::AT_NONE)
{
continue;
}
// MULTI-WEARABLE: DEPRECATED: this message only supports one wearable per type. Should be ignored in future versions
// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id);
outfit->add(wearable_data);
}
LL_DEBUGS() << " " << LLWearableType::getTypeLabel(type) << LL_ENDL;
}
// Get the complete information on the items in the inventory and set up an observer
// that will trigger when the complete information is fetched.
outfit->startFetch();
if(outfit->isFinished())
{
// everything is already here - call done.
outfit->done();
}
else
{
// it's all on it's way - add an observer, and the inventory
// will call done for us when everything is here.
gInventory.addObserver(outfit);
}
}
}
// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the
// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that
// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.)
void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, U32 index)
{
//llassert_always(index == 0);
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
LL_DEBUGS() << "Wearable " << LLWearableType::getTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << LL_ENDL;
LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
setWearable(type,index,new_wearable);
//new_wearable->writeToAvatar( TRUE );
// Add a new one in the lost and found folder.
// (We used to overwrite the "not found" one, but that could potentially
// destory content.) JC
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLPointer<LLInventoryCallback> cb =
new AddWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
type,
index,
new_wearable,
AddWearableToAgentInventoryCallback::CALL_RECOVERDONE);
addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE);
}
void LLAgentWearables::recoverMissingWearableDone()
{
// Have all the wearables that the avatar was wearing at log-in arrived or been fabricated?
updateWearablesLoaded();
if (areWearablesLoaded())
{
// Make sure that the server's idea of the avatar's wearables actually match the wearables.
gAgent.sendAgentSetAppearance();
}
else
{
gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null );
gInventory.notifyObservers();
}
}
void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)
{
LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);
@@ -1205,28 +937,6 @@ void LLAgentWearables::sendDummyAgentWearablesUpdate()
gAgent.sendReliableMessage();
}
void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index)
{
LL_INFOS() << "type " << type << " index " << index << LL_ENDL;
if (!isAgentAvatarValid()) return;
gAgentAvatarp->updateVisualParams();
}
void LLAgentWearables::createStandardWearablesAllDone()
{
// ... because sendAgentWearablesUpdate will notify inventory
// observers.
LL_INFOS() << "all done?" << LL_ENDL;
mWearablesLoaded = TRUE;
notifyLoadingFinished();
updateServer();
// Treat this as the first texture entry message, if none received yet
gAgentAvatarp->onFirstTEMessageReceived();
}
void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
{
@@ -1364,10 +1074,6 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
}
}
queryWearableCache();
// Update the server
updateServer();
gInventory.notifyObservers();
}
@@ -1381,9 +1087,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
llassert(items.size() == count);
// Check for whether outfit already matches the one requested
S32 matched = 0, mismatched = 0, local_updates = 0;
S32 matched = 0, mismatched = 0;
const S32 arr_size = LLWearableType::WT_COUNT;
S32 type_counts[arr_size];
BOOL update_inventory = FALSE;
std::fill(type_counts,type_counts+arr_size,0);
for (S32 i = 0; i < count; i++)
{
@@ -1400,38 +1107,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
S32 index = type_counts[type];
type_counts[type]++;
LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type, index));
const LLUUID curr_id = curr_wearable ? curr_wearable->getItemID() : LLUUID::null;
const std::string curr_name = curr_wearable ? curr_wearable->getName() : std::string();
if (curr_id == new_item->getUUID()) //Nothing to do. No change..
{
matched++;
continue;
}
new_wearable->setName(new_item->getName());
new_wearable->setItemID(new_item->getUUID());
bool matching_asset = new_wearable && curr_wearable && new_wearable->getAssetID() == curr_wearable->getAssetID();
if (matching_asset || LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
{
//Simple replacement at index.
setWearable(type, index, new_wearable); //Stomp the old wearable, but don't increment mismatched. setWearable calls wearableUpdate.
if (new_wearable == curr_wearable) //If both new and cur are the same underlying wearable, then the old id got overwritten in the setItemId call above.
//Need to manually call addChangedMasked on the prior id.
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, curr_id);
}
if (matching_asset)
local_updates++;
else
mismatched++; //Need to update visual parameters and such things.
continue;
}
else
LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type,index));
if (!new_wearable || !curr_wearable ||
new_wearable->getAssetID() != curr_wearable->getAssetID())
{
LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index
<< " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << ","
@@ -1440,10 +1118,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
continue;
}
// Don't care about this case - ordering of wearables with the same asset id has no effect.
// Causes the two-alphas error case in MAINT-4158.
// Update only inventory in this case - ordering of wearables with the same asset id has no effect.
// Updating wearables in this case causes the two-alphas error in MAINT-4158.
// We should actually disallow wearing two wearables with the same asset id.
#if 0
if (curr_wearable->getName() != new_item->getName() ||
curr_wearable->getItemID() != new_item->getUUID())
{
@@ -1454,9 +1131,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
update_inventory = TRUE;
continue;
}
#endif
// If we got here, everything matches.
//matched++; // TODO: Find out why this was here, this became unreachable at some point.
matched++;
}
LL_DEBUGS("Avatar") << "matched " << matched << " mismatched " << mismatched << LL_ENDL;
for (S32 j=0; j<LLWearableType::WT_COUNT; j++)
@@ -1468,15 +1144,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
mismatched++;
}
}
if (mismatched == 0)
if (mismatched == 0 && !update_inventory)
{
LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL;
mCOFChangeInProgress = false;
if (local_updates)
{
LL_DEBUGS("Avatar") << "local_updates " << local_updates << " wearable itemIDs" << LL_ENDL;
gInventory.notifyObservers();
}
notifyLoadingFinished();
return;
}
@@ -1503,20 +1174,45 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
const LLWearableType::EType type = new_wearable->getType();
if (LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING)
LLUUID old_wearable_id = new_wearable->getItemID();
new_wearable->setName(new_item->getName());
new_wearable->setItemID(new_item->getUUID());
if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
{
pushWearable(type,new_wearable); //pushWearable calls wearableUpdate.
// exactly one wearable per body part
setWearable(type,0,new_wearable);
if (old_wearable_id.notNull())
{
// we changed id before setting wearable, update old item manually
// to complete the swap.
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_wearable_id);
}
}
else
{
pushWearable(type,new_wearable);
}
const BOOL removed = FALSE;
wearableUpdated(new_wearable, removed);
}
}
gInventory.notifyObservers();
if (mismatched == 0)
{
LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL;
notifyLoadingFinished();
return;
}
// updating agent avatar
if (isAgentAvatarValid())
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
gAgentAvatarp->writeWearablesToAvatar();
gAgentAvatarp->updateVisualParams();
// If we have not yet declouded, we may want to use
// baked texture UUIDs sent from the first objectUpdate message
@@ -1536,11 +1232,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
if (!mInitialWearablesLoaded)
{
mInitialWearablesLoaded = true;
mInitialWearablesLoadedSignal();
}
// [/SL:KB]
notifyLoadingFinished();
queryWearableCache();
updateServer();
// Copy wearable params to avatar.
gAgentAvatarp->writeWearablesToAvatar();
// Then update the avatar based on the copied params.
gAgentAvatarp->updateVisualParams();
gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
@@ -1663,63 +1364,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// }
//}
void LLAgentWearables::queryWearableCache()
{
if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))
{
return;
}
// Look up affected baked textures.
// If they exist:
// disallow updates for affected layersets (until dataserver responds with cache request.)
// If cache miss, turn updates back on and invalidate composite.
// If cache hit, modify baked texture entries.
//
// Cache requests contain list of hashes for each baked texture entry.
// Response is list of valid baked texture assets. (same message)
gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->addS32Fast(_PREHASH_SerialNum, gAgentQueryManager.mWearablesCacheQueryID);
S32 num_queries = 0;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
{
LLUUID hash_id = computeBakedTextureHash((EBakedTextureIndex) baked_index);
if (hash_id.notNull())
{
num_queries++;
// *NOTE: make sure at least one request gets packed
ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
//LL_INFOS() << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << LL_ENDL;
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addUUIDFast(_PREHASH_ID, hash_id);
gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)te_index);
}
gAgentQueryManager.mActiveCacheQueries[ baked_index ] = gAgentQueryManager.mWearablesCacheQueryID;
}
//VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout
if(gAgent.getRegion())
{
if (isAgentAvatarValid())
{
selfStartPhase("fetch_texture_cache_entries");
gAgentAvatarp->outputRezTiming("Fetching textures from cache");
}
LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
gAgentQueryManager.mNumPendingQueries++;
gAgentQueryManager.mWearablesCacheQueryID++;
}
}
// User has picked "remove from avatar" from a menu.
// static
//void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
@@ -1883,72 +1527,12 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
static bool sInitialAttachmentsRequested = false;
// RELEASE-RLVa: [SL-3.4] Check our callers and verify that erasing elements from the passed vector won't break random things
if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
{
// Fall-back code: everything should really already have been pruned before we get this far
LLInventoryModel::item_array_t::size_type cntAttach = obj_item_array.size();
obj_item_array.erase(std::remove_if(obj_item_array.begin(), obj_item_array.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_item_array.end());
RLV_ASSERT(cntAttach == obj_item_array.size());
}
// [/RLVa:KB]
// Build a compound message to send all the objects that need to be rezzed.
S32 obj_count = obj_item_array.size();
// Limit number of packets to send
const S32 MAX_PACKETS_TO_SEND = 10;
const S32 OBJECTS_PER_PACKET = 4;
const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
if( obj_count > MAX_OBJECTS_TO_SEND )
if (obj_count > 0)
{
obj_count = MAX_OBJECTS_TO_SEND;
LL_DEBUGS("Avatar") << "ATT attaching multiple, total obj_count " << obj_count << LL_ENDL;
}
// Create an id to keep the parts of the compound message together
LLUUID compound_msg_id;
compound_msg_id.generate();
LLMessageSystem* msg = gMessageSystem;
for(S32 i = 0; i < obj_count; ++i)
{
if( 0 == (i % OBJECTS_PER_PACKET) )
{
// Start a new message chunk
msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->nextBlockFast(_PREHASH_HeaderData);
msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
msg->addBOOLFast(_PREHASH_FirstDetachAll, false );
}
const LLInventoryItem* item = obj_item_array.at(i).get();
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
msg->addU8Fast(_PREHASH_AttachmentPt, ATTACHMENT_ADD); // Wear at the previous or default attachment point
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
{
RlvAttachmentLockWatchdog::instance().onWearAttachment(item, RLV_WEAR_ADD);
}
// [/RLVa:KB]
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
msg->addStringFast(_PREHASH_Name, item->getName());
msg->addStringFast(_PREHASH_Description, item->getDescription());
if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
{
// End of message chunk
msg->sendReliable( gAgent.getRegion()->getHost() );
}
for(LLInventoryModel::item_array_t::const_iterator it = obj_item_array.begin();
it != obj_item_array.end();
@@ -1959,7 +1543,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
}
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
sInitialAttachmentsRequested = true;
mInitialAttachmentsRequested = true;
// [/RLVa:KB]
}
@@ -1982,16 +1566,6 @@ BOOL LLAgentWearables::areWearablesLoaded() const
return mWearablesLoaded;
}
// MULTI-WEARABLE: DEPRECATED: item pending count relies on old messages that don't support multi-wearables. do not trust to be accurate
void LLAgentWearables::updateWearablesLoaded()
{
mWearablesLoaded = (itemUpdatePendingCount()==0);
if (mWearablesLoaded)
{
notifyLoadingFinished();
}
}
bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const
{
if (!wearable) return false;
@@ -2155,30 +1729,6 @@ void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id)
}
}
void LLAgentWearables::updateServer()
{
sendAgentWearablesUpdate();
gAgent.sendAgentSetAppearance();
}
void LLAgentWearables::populateMyOutfitsFolder(void)
{
LL_INFOS() << "starting outfit population" << LL_ENDL;
const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(my_outfits_id);
outfits->mMyOutfitsID = my_outfits_id;
// Get the complete information on the items in the inventory and
// setup an observer that will wait for that to happen.
gInventory.addObserver(outfits);
outfits->startFetch();
if (outfits->isFinished())
{
outfits->done();
}
}
boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb)
{
return mLoadingStartedSignal.connect(cb);
@@ -2194,6 +1744,13 @@ bool LLAgentWearables::changeInProgress() const
return mCOFChangeInProgress;
}
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(const loaded_callback_t& cb)
{
return mInitialWearablesLoadedSignal.connect(cb);
}
// [/SL:KB]
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;

View File

@@ -42,7 +42,6 @@
class LLInventoryItem;
class LLVOAvatarSelf;
class LLViewerWearable;
class LLInitialWearablesFetch;
class LLViewerObject;
class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData
@@ -62,9 +61,6 @@ public:
// LLInitClass interface
static void initClass();
protected:
void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
void createStandardWearablesAllDone();
//--------------------------------------------------------------------
// Queries
@@ -76,9 +72,12 @@ public:
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
BOOL areWearablesLoaded() const;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
bool areInitalWearablesLoaded() const { return mInitialWearablesLoaded; }
// [/SL:KB]
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
bool areInitialAttachmentsRequested() const { return mInitialAttachmentsRequested; }
// [/RLVa:KB]
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
F32 getCOFChangeTime() const { return mCOFChangeTimer.getElapsedTimeF32(); }
void updateWearablesLoaded();
@@ -94,7 +93,7 @@ public:
// Accessors
//--------------------------------------------------------------------
public:
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0)
void getWearableItemIDs(uuid_vec_t& idItems) const;
void getWearableItemIDs(LLWearableType::EType eType, uuid_vec_t& idItems) const;
// [/RLVa:KB]
@@ -122,8 +121,8 @@ public:
void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index);
protected:
void setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
// void setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
// static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
LLViewerWearable* wearable,
@@ -155,36 +154,18 @@ private:
// Removing wearables
//--------------------------------------------------------------------
public:
void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
// void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
private:
// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0)
void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
// [/RLVa:KB]
void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
protected:
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
//--------------------------------------------------------------------
// Server Communication
//--------------------------------------------------------------------
public:
// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
protected:
void sendAgentWearablesUpdate();
void sendAgentWearablesRequest();
void queryWearableCache();
void updateServer();
static void onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata);
//--------------------------------------------------------------------
// Outfits
//--------------------------------------------------------------------
public:
// Should only be called if we *know* we've never done so before, since users may
// not want the Library outfits to stay in their quick outfit selector and can delete them.
void populateMyOutfitsFolder();
private:
void makeNewOutfitDone(S32 type, U32 index);
@@ -219,9 +200,6 @@ public:
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
BOOL itemUpdatePending(const LLUUID& item_id) const;
U32 itemUpdatePendingCount() const;
//--------------------------------------------------------------------
// Signals
//--------------------------------------------------------------------
@@ -233,6 +211,9 @@ public:
typedef boost::function<void()> loaded_callback_t;
typedef boost::signals2::signal<void()> loaded_signal_t;
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
boost::signals2::connection addInitialWearablesLoadedCallback(const loaded_callback_t& cb);
// [/SL:KB]
bool changeInProgress() const;
void notifyLoadingStarted();
@@ -241,17 +222,22 @@ public:
private:
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
loaded_signal_t mInitialWearablesLoadedSignal; // emitted once when the initial wearables are loaded
// [/SL:KB]
//--------------------------------------------------------------------
// Member variables
//--------------------------------------------------------------------
private:
static BOOL mInitialWearablesUpdateReceived;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.2)
static bool mInitialWearablesLoaded;
// [/SL:KB]
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
static bool mInitialAttachmentsRequested;
// [/RLVa:KB]
BOOL mWearablesLoaded;
std::set<LLUUID> mItemsAwaitingWearableUpdate;
/**
* True if agent's outfit is being changed now.

View File

@@ -3132,9 +3132,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
// msg->setHandlerFuncFast(_PREHASH_ReputationIndividualReply,
// LLFloaterRate::processReputationIndividualReply);
msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate,
LLAgentWearables::processAgentInitialWearablesUpdate );
msg->setHandlerFunc("ScriptControlChange",
LLAgent::processScriptControlChange );