RLVa update.

This commit is contained in:
Shyotl
2013-03-26 00:46:11 -05:00
parent 1705167998
commit 441b564afe
32 changed files with 585 additions and 364 deletions

View File

@@ -465,6 +465,13 @@ void LLAvatarAppearance::computeBodySize()
LLVector3 foot = mFootLeftp->getPosition();
LLVector3 old_offset = mAvatarOffset;
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
mAvatarOffset = getAvatarOffset();
// [/RLVa:KB]
// mAvatarOffset.mV[VZ] = getVisualParamWeight(11001);
mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
knee.mV[VZ] * hip_scale.mV[VZ] -
ankle.mV[VZ] * knee_scale.mV[VZ] -
@@ -484,13 +491,23 @@ void LLAvatarAppearance::computeBodySize()
new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
if (new_body_size != mBodySize)
//mAvatarOffset.mV[VX] = 0.0f;
//mAvatarOffset.mV[VY] = 0.0f;
if (new_body_size != mBodySize || old_offset != mAvatarOffset)
{
mBodySize = new_body_size;
bodySizeChanged();
}
}
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
LLVector3 LLAvatarAppearance::getAvatarOffset() /*const*/
{
return LLVector3(0.f,0.f,getVisualParamWeight(11001));
}
// [/RLVa:KB]
//-----------------------------------------------------------------------------
// parseSkeletonFile()
//-----------------------------------------------------------------------------

View File

@@ -150,6 +150,9 @@ protected:
virtual void buildCharacter();
virtual BOOL loadAvatar();
virtual void bodySizeChanged() = 0;
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
virtual LLVector3 getAvatarOffset() /*const*/;
// [/RLVa:KB]
BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
BOOL allocateCharacterJoints(U32 num);
@@ -165,6 +168,7 @@ protected:
//--------------------------------------------------------------------
public:
LLVector3 mBodySize;
LLVector3 mAvatarOffset;
protected:
F32 mPelvisToFoot;

View File

@@ -104,19 +104,12 @@ U32 LLWearableData::pushWearable(const LLWearableType::EType type,
llwarns << "Null wearable sent for type " << type << llendl;
return MAX_CLOTHING_PER_TYPE;
}
// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
// {
// mWearableDatas[type].push_back(wearable);
// wearableUpdated(wearable);
// checkWearableAgainstInventory(wearable);
// return mWearableDatas[type].size()-1;
// }
// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) )
{
// Don't add the same wearable twice
U32 idxWearable = getWearableIndex(wearable);
//RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere*
llassert(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere*
if (MAX_CLOTHING_PER_TYPE == idxWearable)
{
mWearableDatas[type].push_back(wearable);
@@ -128,8 +121,18 @@ U32 LLWearableData::pushWearable(const LLWearableType::EType type,
wearableUpdated(wearable, removed);
}
return idxWearable;
// [/RLVa:KB]
}
// [/RLVa:KB]
// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
// {
// mWearableDatas[type].push_back(wearable);
// if (trigger_updated)
// {
// const BOOL removed = FALSE;
// wearableUpdated(wearable, removed);
// }
// return mWearableDatas[type].size()-1;
// }
return MAX_CLOTHING_PER_TYPE;
}

View File

@@ -99,7 +99,10 @@ LLWearableDictionary::LLWearableDictionary()
addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
// addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-05-29 (Catznip-2.6)
addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE));
// [/SL:KB]
addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));

View File

@@ -823,7 +823,24 @@
<bone name="mNeck" scale="0 0 .5" />
</param_skeleton>
</param>
</skeleton>
<param
id="11001"
group="0"
name="Hover"
wearable="shape"
edit_group="shape_body"
edit_group_order="4"
label_min="Lower"
label_max="Higher"
value_min="-2"
value_max="2"
value_default="0"
camera_distance="2.5">
<param_skeleton />
</param>
</skeleton>
<mesh
type="hairMesh"

View File

@@ -2876,9 +2876,9 @@ void LLAgent::buildFullnameAndTitle(std::string& name) const
}
}
BOOL LLAgent::isInGroup(const LLUUID& group_id) const
BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */) const
{
if (isGodlike())
if (!ignore_god_mode && isGodlike())
return true;
S32 count = mGroups.count();
@@ -3102,13 +3102,13 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
void LLAgent::setAlwaysRun()
{
mbAlwaysRun = true;//(!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_ALWAYSRUN));
mbAlwaysRun = (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_ALWAYSRUN));
sendWalkRun();
}
void LLAgent::setTempRun()
{
mbTempRun = true;//(!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_TEMPRUN));
mbTempRun = (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_TEMPRUN));
sendWalkRun();
}
@@ -4527,19 +4527,7 @@ void LLAgent::sendAgentSetAppearance()
// NOTE -- when we start correcting all of the other Havok geometry
// to compensate for the COLLISION_TOLERANCE ugliness we will have
// to tweak this number again
LLVector3 body_size = gAgentAvatarp->mBodySize;
static LLCachedControl<F32> x_off("AscentAvatarXModifier");
static LLCachedControl<F32> y_off("AscentAvatarYModifier");
static LLCachedControl<F32> z_off("AscentAvatarZModifier");
body_size.mV[VX] += x_off;
body_size.mV[VY] += y_off;
body_size.mV[VZ] += z_off; // Offset by RLVa, but not overridden.
// [RLVa:KB] - Checked: 2010-10-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
body_size.mV[VZ] += RlvSettings::getAvatarOffsetZ();
// [/RLVa:KB]
const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset;
msg->addVector3Fast(_PREHASH_Size, body_size);
// To guard against out of order packets

View File

@@ -811,7 +811,7 @@ private:
//--------------------------------------------------------------------
public:
// Checks against all groups in the entire agent group list.
BOOL isInGroup(const LLUUID& group_id) const;
BOOL isInGroup(const LLUUID& group_id, BOOL ingnore_God_mod = FALSE) const;
protected:
// Only used for building titles.
BOOL isGroupMember() const { return !mGroupID.isNull(); }

View File

@@ -1209,11 +1209,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
{
LLViewerWearable* old_wearable = getViewerWearable(type,index);
// if (old_wearable)
// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g
// NOTE: we block actual removal in removeWearableFinal(); all we really want here is to avoid showing the save notice
if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) )
// [/RLVa:KB]
if (old_wearable)
{
if (old_wearable->isDirty())
{
@@ -1271,19 +1267,16 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
{
LLViewerWearable* old_wearable = getViewerWearable(type,i);
//queryWearableCache(); // moved below
// if (old_wearable)
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) )
// [/RLVa:KB]
if (old_wearable)
{
popWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
}
}
// mWearableDatas[type].clear();
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
// The line above shouldn't be needed and would cause issues if we block removing one of the wearables
RLV_VERIFY( ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.hasLockedWearable(type))) ? mWearableDatas[type].empty() : true );
// clearWearableType(type);
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0)
// The line above shouldn't be needed
RLV_VERIFY(0 == getWearableCount(type));
// [/RLVa:KB]
}
else
@@ -1291,10 +1284,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_
LLViewerWearable* old_wearable = getViewerWearable(type, index);
//queryWearableCache(); // moved below
// if (old_wearable)
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) )
// [/RLVa:KB]
if (old_wearable)
{
popWearable(old_wearable);
old_wearable->removeFromAvatar(TRUE);
@@ -1356,12 +1346,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
S32 count = wearables.count();
llassert(items.count() == count);
// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
// If the user is @add/remoutfit restricted in any way then this function won't just work as-is, so instead of removing and re-adding
// we're stuck with any wearable type potentially having left-over (remove locked) clothing that we'll need to reorder in-place
S32 idxCurPerType[LLWearableType::WT_COUNT] = { 0 };
// [/RLVa:KB]
S32 i;
for (i = 0; i < count; i++)
{
@@ -1386,51 +1370,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// exactly one wearable per body part
setWearable(type,0,new_wearable);
}
// else
// {
// pushWearable(type,new_wearable);
// }
// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
else if ( (!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.hasLockedWearable(type)) || (!remove) )
{
// Sanity check: there shouldn't be any worn wearables for this type the first time we encounter it
RLV_ASSERT( (!remove) || (0 != idxCurPerType[type]) || (0 == getWearableCount(type)) );
pushWearable(type,new_wearable);
}
else
{
// Get the current index of the wearable (or add it if doesn't exist yet)
S32 idxCur = getWearableIndex(new_wearable);
if (MAX_CLOTHING_PER_TYPE == idxCur)
{
// Skip adding if @addoutfit=n restricted *unless* the wearable made it into COF [see LLAppMgr::updateAgentWearables()]
if ( (RLV_WEAR_LOCKED == gRlvWearableLocks.canWear(type)) &&
(!gInventory.isObjectDescendentOf(new_item->getUUID(), LLAppearanceMgr::instance().getCOF())) )
{
continue;
}
idxCur = pushWearable(type,new_wearable);
}
// Since we're moving up from index 0 we just swap the two wearables and things will work out in the end (hopefully)
if (idxCurPerType[type] != idxCur)
{
wearableentry_map_t::iterator itWearable = mWearableDatas.find(type);
RLV_ASSERT(itWearable != mWearableDatas.end());
if (itWearable == mWearableDatas.end()) continue;
wearableentry_vec_t& typeWearable = itWearable->second;
RLV_ASSERT(typeWearable.size() >= 2);
if (typeWearable.size() < 2) continue;
typeWearable[idxCur] = typeWearable[idxCurPerType[type]];
typeWearable[idxCurPerType[type]] = new_wearable;
//wearableUpdated(new_wearable);
//checkWearableAgainstInventory(new_wearable);
}
pushWearable(type,new_wearable);
}
idxCurPerType[type]++;
// [/RLVa:KB]
const BOOL removed = FALSE;
wearableUpdated(new_wearable, removed);
}
@@ -1475,7 +1418,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// User has picked "wear on avatar" from a menu.
void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
/*void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
{
//LLAgentDumper dumper("setWearableItem");
if (isWearingItem(new_item->getUUID()))
@@ -1523,7 +1466,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearab
}
setWearableFinal(new_item, new_wearable, do_append);
}
}*/
// static
bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable)
@@ -1696,8 +1639,8 @@ void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
//void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly)
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2)
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool attach_only)
// [/SL:KB]
{
// Possible cases:
@@ -1764,8 +1707,8 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
// Remove everything in objects_to_remove
// userRemoveMultipleAttachments(objects_to_remove);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a
if (!fAttachOnly)
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2)
if (!attach_only)
{
userRemoveMultipleAttachments(objects_to_remove);
}
@@ -1779,12 +1722,12 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
{
if (!isAgentAvatarValid()) return;
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
// RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0)
// 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()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) )
{
llvo_vec_t::iterator itObj = objects_to_remove.begin();
while (itObj != objects_to_remove.end())
while (objects_to_remove.end() != itObj)
{
const LLViewerObject* pAttachObj = *itObj;
if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj))
@@ -1792,12 +1735,12 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
itObj = objects_to_remove.erase(itObj);
// Fall-back code: re-add the attachment if it got removed from COF somehow (compensates for possible bugs elsewhere)
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
LLLinkedItemIDMatches f(pAttachObj->getAttachmentItemID());
gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f);
RLV_ASSERT( 0 != items.count() );
if (0 == items.count())
bool fInCOF = LLAppearanceMgr::isLinkInCOF(pAttachObj->getAttachmentItemID());
RLV_ASSERT(fInCOF);
if (!fInCOF)
{
LLAppearanceMgr::instance().registerAttachment(pAttachObj->getAttachmentItemID());
}
}
else
{
@@ -1828,10 +1771,10 @@ 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.1b) | Added: RLVa-1.3.1b
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1)
static bool sInitialAttachmentsRequested = false;
// RELEASE-RLVa: [SL-2.5.2] Check our callers and verify that erasing elements from the passed vector won't break random things
// 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

View File

@@ -113,7 +113,7 @@ public:
private:
/*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed);
public:
void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
// void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
void setWearableName(const LLUUID& item_id, const std::string& new_name);
// *TODO: Move this into llappearance/LLWearableData ?

View File

@@ -1374,30 +1374,11 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
return false;
}
// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a
if ( (rlv_handler_t::isEnabled()) &&
((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY))) )
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
replace |= (LLAssetType::AT_BODYPART == item_to_wear->getType()); // Body parts should always replace
if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item_to_wear, (replace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) )
{
switch (item_to_wear->getType())
{
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
{
ERlvWearMask eWear = gRlvWearableLocks.canWear(item_to_wear);
if ( (RLV_WEAR_LOCKED == eWear) || ((replace) && ((RLV_WEAR_REPLACE & eWear) == 0)) )
return false;
}
break;
case LLAssetType::AT_OBJECT:
{
ERlvWearMask eWear = gRlvAttachmentLocks.canAttach(item_to_wear);
if ( (RLV_WEAR_LOCKED == eWear) || ((replace) && ((RLV_WEAR_REPLACE & eWear) == 0)) )
return false;
}
break;
default:
return false;
}
return false;
}
// [/RLVa:KB]
@@ -1793,25 +1774,56 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
}
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter)
void LLAppearanceMgr::purgeItems(const LLInventoryModel::item_array_t& items)
{
for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem)
{
const LLViewerInventoryItem* pItem = *itItem;
if (pItem->getIsLinkType())
{
gInventory.purgeObject(pItem->getUUID());
}
}
}
void LLAppearanceMgr::purgeItemsOfType(LLAssetType::EType asset_type)
{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH);
for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem)
{
const LLInventoryItem* pItem = *itItem;
if ( (pItem->getIsLinkType()) && (asset_type == pItem->getType()) )
{
gInventory.purgeObject(pItem->getUUID());
}
}
}
void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items,
LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove)
{
const LLUUID idCOF = getCOF();
LLInventoryModel::item_array_t cur_cof_items, new_cof_items = items;
// Grab the current COF contents
LLIsType f(type);
LLInventoryModel::cat_array_t cats;
gInventory.collectDescendentsIf(getCOF(), cats, cur_cof_items, LLInventoryModel::EXCLUDE_TRASH, f);
gInventory.collectDescendents(getCOF(), cats, cur_cof_items, LLInventoryModel::EXCLUDE_TRASH);
// Purge everything in cur_cof_items that isn't part of new_cof_items
for (S32 idxCurItem = 0, cntCurItem = cur_cof_items.count(); idxCurItem < cntCurItem; idxCurItem++)
{
const LLViewerInventoryItem* pItem = cur_cof_items.get(idxCurItem);
LLViewerInventoryItem* pItem = cur_cof_items.get(idxCurItem);
if (std::find_if(new_cof_items.begin(), new_cof_items.end(), RlvPredIsEqualOrLinkedItem(pItem)) == new_cof_items.end())
{
// Item doesn't exist in new_cof_items => purge (if it's a link)
if (pItem->getIsLinkType())
gInventory.purgeObject(pItem->getUUID());
if ( (pItem->getIsLinkType()) &&
(LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) &&
(items_to_remove.end() == std::find(items_to_remove.begin(), items_to_remove.end(), pItem)) )
{
items_to_remove.push_back(pItem);
}
}
else
{
@@ -1821,10 +1833,14 @@ void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAss
}
}
// Link to whatever remains in new_cof_items
// Whatever remains in new_cof_items will need to have a link created
for (S32 idxNewItem = 0, cntNewItem = new_cof_items.count(); idxNewItem < cntNewItem; idxNewItem++)
{
link_waiter->addItem(new_cof_items.get(idxNewItem)->getLinkedUUID());
LLViewerInventoryItem* pItem = new_cof_items.get(idxNewItem);
if (items_to_add.end() == std::find(items_to_add.begin(), items_to_add.end(), pItem))
{
items_to_add.push_back(pItem);
}
}
}
// [/SL:KB]
@@ -1893,11 +1909,12 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
getDescendentsOfAssetType(category, gest_items_new, LLAssetType::AT_GESTURE, false);
updateCOF(body_items_new, wear_items_new, obj_items_new, gest_items_new, append, category);
}
void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
LLInventoryModel::item_array_t& wear_items_new,
LLInventoryModel::item_array_t& obj_items_new,
LLInventoryModel::item_array_t& gest_items_new,
bool append /*=false*/, const LLUUID& category /*=LLUUID::null*/)
bool append /*=false*/, const LLUUID& idOutfit /*=LLUUID::null*/)
// [/RLVa:KB]
{
// LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
@@ -2006,60 +2023,57 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new,
// [/RLVa:KB]
removeDuplicateItems(gest_items);
#ifndef LL_RELEASE_FOR_DOWNLOAD
LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
#endif
// Create links to new COF contents.
LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL;
LLInventoryModel::item_array_t all_items;
/*all_items += body_items;
all_items += body_items;
all_items += wear_items;
all_items += obj_items;
all_items += gest_items;*/
all_items += gest_items;
// Will link all the above items.
bool update_base_outfit_ordering = !append;
LLCallAfterInventoryLinkMgr *link_waiter =
new LLCallAfterInventoryLinkMgr(all_items,cof,"update_appearance_on_destroy",
boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF,
LLAppearanceMgr::getInstance(),
update_base_outfit_ordering));
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
if(append)
{
// Synchronize COF
// -> it's possible that we don't link to any new items in which case 'link_waiter' fires when it goes out of scope below
syncCOF(body_items, LLAssetType::AT_BODYPART, link_waiter);
syncCOF(wear_items, LLAssetType::AT_CLOTHING, link_waiter);
syncCOF(obj_items, LLAssetType::AT_OBJECT, link_waiter);
syncCOF(gest_items, LLAssetType::AT_GESTURE, link_waiter);
}
// [SL:KB]
// Synchronize COF
// -> it's possible that we don't link to any new items in which case 'link_waiter' fires when it goes out of scope below
LLInventoryModel::item_array_t items_add, items_remove;
syncCOF(all_items, items_add, items_remove);
// [/SL:KB]
// Will link all the above items.
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
// [SL:KB] - Checked: 2013-03-05 (RLVa-1.4.8)
linkAll(cof, items_add, link_waiter);
// [/SL:KB]
// linkAll(cof,all_items,link_waiter);
// Add link to outfit if category is an outfit.
// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.0b
if (!append && category.notNull())
// [/RLVa:KB]
if (!append)
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
if ( (!append) && (idOutfit.notNull()) )
{
link_waiter->addItems(body_items);
link_waiter->addItems(wear_items);
link_waiter->addItems(obj_items);
link_waiter->addItems(gest_items);
if(category.notNull())
link_waiter->addItem(category);
createBaseOutfitLink(idOutfit, link_waiter);
}
// [/SL:KB]
// if (!append)
// {
// createBaseOutfitLink(category, link_waiter);
// }
//
// Remove current COF contents. Have to do this after creating
// the link_waiter so links can be followed for any items that get
// carried over (e.g. keeping old shape if the new outfit does not
// contain one)
// [SL:KB]
purgeItems(items_remove);
bool keep_outfit_links = append;
purgeCategory(cof, keep_outfit_links);
if (!keep_outfit_links)
{
purgeItemsOfType(LLAssetType::AT_LINK_FOLDER);
}
gInventory.notifyObservers();
// [/SL:KB]
// bool keep_outfit_links = append;
// purgeCategory(cof, keep_outfit_links, &all_items);
// gInventory.notifyObservers();
LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
}
@@ -2163,7 +2177,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
// We need to report removals before additions or scripts will get confused
for (uuid_vec_t::const_iterator itItemID = idsCurrent.begin(); itItemID != idsCurrent.end(); ++itItemID)
{
const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID);
const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID);
if (pWearable)
RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
}
@@ -2317,7 +2331,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
//dumpCat(getCOF(),"COF, start");
bool follow_folder_links = true;
bool follow_folder_links = false;
LLUUID current_outfit_id = getCOF();
// Find all the wearables that are in the COF's subtree.
@@ -2362,13 +2376,15 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
if (pItem)
{
obj_items.push_back(pItem);
}
++itPendingAttachLink;
}
// Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on)
llinfos << "Updating " << obj_items.count() << " attachments" << llendl;
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.count() << " attachments" << LL_ENDL;
LLAgentWearables::userUpdateAttachments(obj_items, !gAgentAvatarp->isFullyLoaded());
}
// [/SL:KB]
@@ -2908,14 +2924,9 @@ void LLAppearanceMgr::removeAllClothesFromAvatar()
is_clothing,
false);
uuid_vec_t item_ids;
// Take them off by removing from COF.
for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin();
for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
it != clothing_items.end(); ++it)
{
// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(*it)) )
continue;
// [/RLVa:KB]
item_ids.push_back((*it).get()->getLinkedUUID());
}
@@ -2970,6 +2981,16 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id)
const LLInventoryItem* item = item_array.get(i).get();
if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
{
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// NOTE-RLVa: debug-only, can be removed down the line
if (rlv_handler_t::isEnabled())
{
RLV_ASSERT(rlvPredCanRemoveItem(item));
}
#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// [/RLVa:KB]
gInventory.purgeObject(item->getUUID());
}
}
@@ -2988,6 +3009,16 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type)
const LLViewerInventoryItem* item = *it;
if (item->getIsLinkType()) // we must operate on links only
{
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// NOTE-RLVa: debug-only, can be removed down the line
if (rlv_handler_t::isEnabled())
{
RLV_ASSERT(rlvPredCanRemoveItem(item));
}
#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// [/RLVa:KB]
gInventory.purgeObject(item->getUUID());
}
}
@@ -3886,40 +3917,49 @@ void LLAppearanceMgr::wearBaseOutfit()
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
if (ids_to_remove.empty())
{
llwarns << "called with empty list, nothing to do" << llendl;
}
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
bool fUpdateAppearance = false;
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d
// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.1c
LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
if (!item_to_remove)
continue;
if (rlv_handler_t::isEnabled() && !gRlvWearableLocks.canRemove(item_to_remove))
continue;
if (item_to_remove->getType() == LLAssetType::AT_CLOTHING)
const LLInventoryItem* linked_item = gInventory.getLinkedItem(*it);
if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) )
{
const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID());
if(!pWearable || pWearable->getAssetType() == LLAssetType::AT_BODYPART || gAgentWearables.getWearableIndex(pWearable) >= LLAgentWearables::MAX_CLOTHING_PER_TYPE )
continue;
RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
}
// [/RLVa:KB]
removeCOFItemLinks(linked_item_id);
continue;
}
fUpdateAppearance = true;
removeCOFItemLinks(linked_item->getUUID());
}
updateAppearanceFromCOF();
if (fUpdateAppearance)
{
updateAppearanceFromCOF();
}
// [/RLVa:KB]
// for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
// {
// const LLUUID& id_to_remove = *it;
// const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
// removeCOFItemLinks(linked_item_id);
// }
// updateAppearanceFromCOF();
}
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
{
LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
removeCOFItemLinks(linked_item_id);
// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
const LLInventoryItem* linked_item = gInventory.getLinkedItem(id_to_remove);
if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) )
{
return;
}
removeCOFItemLinks(linked_item->getUUID());
updateAppearanceFromCOF();
// [/RLVA:KB]
// LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
// removeCOFItemLinks(linked_item_id);
// updateAppearanceFromCOF();
}
bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)

View File

@@ -239,7 +239,10 @@ private:
void setOutfitLocked(bool locked);
// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter);
void purgeItems(const LLInventoryModel::item_array_t& items);
void purgeItemsOfType(LLAssetType::EType asset_type);
void syncCOF(const LLInventoryModel::item_array_t& items,
LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove);
// [/SL:KB]
bool mAttachmentInvLinkEnabled;

View File

@@ -203,6 +203,9 @@
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
#include "llappearancemgr.h"
// [/SL:KB]
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
@@ -4454,7 +4457,8 @@ void LLAppViewer::idleNetwork()
gObjectList.mNumNewObjects = 0;
S32 total_decoded = 0;
if (!gSavedSettings.getBOOL("SpeedTest"))
static const LLCachedControl<bool> speedTest(gSavedSettings, "SpeedTest");
if (!speedTest)
{
LLFastTimer t(FTM_IDLE_NETWORK); // decode
@@ -4633,6 +4637,10 @@ void LLAppViewer::disconnectViewer()
// close inventory interface, close all windows
LLInventoryView::cleanup();
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
// Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false);
// [/SL:KB]
gAgentWearables.cleanup();
gAgentCamera.cleanup();

View File

@@ -46,6 +46,11 @@
#include "llmutelist.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.2a)
#include "llavatarnamecache.h"
#include "rlvhandler.h"
#include "rlvui.h"
// [/RLVa:KB]
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES
// or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a

View File

@@ -492,7 +492,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
// LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
// if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
// {
// // bubble off-screen, so find a spot for it along screen edge
@@ -690,17 +690,14 @@ F32 LLHUDText::LLHUDTextSegment::getWidth(const LLFontGL* font)
}
}
// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
void LLHUDText::refreshAllObjectText()
{
for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); itText++)
for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); ++itText)
{
LLHUDText* pText = *itText;
if ( (pText) && (!pText->getPreFilteredText().empty() && ("" != pText->getPreFilteredText()) ) &&
(pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) )
{
pText->setString(pText->mPreFilteredText);
}
if ( (pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) )
pText->setString(pText->mObjText);
}
}
// [/RLVa:KB]

View File

@@ -124,8 +124,10 @@ public:
static void renderAllHUD();
static void reshape();
static void setDisplayText(BOOL flag) { sDisplayText = flag ; }
// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
const std::string &getPreFilteredText() const {return mPreFilteredText;}
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
const std::string& getObjectText() const { return mObjText; }
void setObjectText(const std::string &utf8string) { mObjText = utf8string; }
static void refreshAllObjectText();
// [/RLVa:KB]
@@ -170,8 +172,8 @@ private:
ETextAlignment mTextAlignment;
EVertAlignment mVertAlignment;
BOOL mHidden;
// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f
std::string mPreFilteredText;
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
std::string mObjText;
// [/RLVa:KB]
static BOOL sDisplayText ;

View File

@@ -1722,12 +1722,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
return ACCEPT_NO;
}
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8)
bool fReplace = !(mask & MASK_CONTROL);
if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item, (fReplace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) )
{
ERlvWearMask eWearMask = gRlvAttachmentLocks.canAttach(item); bool fReplace = !(mask & MASK_CONTROL);
if ( ((!fReplace) && ((RLV_WEAR_ADD & eWearMask) == 0)) || ((fReplace) && ((RLV_WEAR_REPLACE & eWearMask) == 0)) )
return ACCEPT_NO_LOCKED;
return ACCEPT_NO_LOCKED;
}
// [/RLVa:KB]
@@ -2086,12 +2085,11 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem(
return ACCEPT_NO;
}
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8)
bool fReplace = (!(mask & MASK_CONTROL)) || (LLAssetType::AT_BODYPART == item->getType()); // Body parts should always replace
if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item, (fReplace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) )
{
ERlvWearMask eWearMask = gRlvWearableLocks.canWear(item); bool fReplace = !(mask & MASK_CONTROL);
if ( ((!fReplace) && ((RLV_WEAR_ADD & eWearMask) == 0)) || ((fReplace) && ((RLV_WEAR_REPLACE & eWearMask) == 0)) )
return ACCEPT_NO_LOCKED;
return ACCEPT_NO_LOCKED;
}
// [/RLVa:KB]
@@ -2107,7 +2105,10 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem(
// TODO: investigate wearables may not be loaded at this point EXT-8231
LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8)
LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, fReplace);
// [/RLVa:KB]
// LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL));
}
return ACCEPT_YES_MULTI;
}

View File

@@ -45,6 +45,9 @@
#include "llworld.h"
#include "lltoolmgr.h"
#include "llviewerjoystick.h"
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e)
#include "rlvhandler.h"
// [/RLVa:KB]
// Linden library includes
#include "lldrawable.h"
@@ -350,7 +353,10 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
if (limit_select_distance)
{
// ...select distance from control
z_far = gSavedSettings.getF32("MaxSelectDistance");
// z_far = gSavedSettings.getF32("MaxSelectDistance");
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
z_far = (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ? gSavedSettings.getF32("MaxSelectDistance") : 1.5;
// [/RLVa:KB]
}
else
{

View File

@@ -1517,6 +1517,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
sizeof(mFolderID.mData));
// send the message
msg->sendReliable(mHost);
// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Added: RLVa-1.2.1e
if (fRlvNotifyAccepted)
{
std::string::size_type idxToken = mDesc.find("' ( http://");
if (std::string::npos != idxToken)
RlvBehaviourNotifyHandler::sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1));
}
// [/RLVa:KB]
//don't spam them if they are getting flooded
if (check_offer_throttle(mFromName, true))
@@ -6525,12 +6534,6 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
{
// got the region, so include the region and 3d coordinates of the object
notice.setArg("[REGIONNAME]", viewregion->getName());
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) )
{
notice.setArg("[REGIONNAME]", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
}
// [/RLVa:KB]
std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]);
notice.setArg("[REGIONPOS]", formatpos);
@@ -6538,7 +6541,15 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
}
}
if (!foundpos)
// [RLVa:KB] - Checked: 2010-04-23 (RLVa-1.2.0g) | Modified: RLVa-1.0.0a
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
{
notice.setArg("[REGIONNAME]", RlvStrings::getString(RLV_STRING_HIDDEN_REGION));
notice.setArg("[REGIONPOS]", RlvStrings::getString(RLV_STRING_HIDDEN));
}
else if (!foundpos)
// [/RLVa:KB]
// if (!foundpos)
{
// unable to determine location of the object
notice.setArg("[REGIONNAME]", "(unknown region)");
@@ -6552,7 +6563,11 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
std::string perms;
for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
{
if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
// if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
if ( (orig_questions & LSCRIPTRunTimePermissionBits[i]) &&
((SCRIPT_QUESTION_IS_CAUTION[i]) || (notification["payload"]["rlv_notify"].asBoolean())) )
// [/RLVa:KB]
{
count++;
caution = TRUE;

View File

@@ -1270,6 +1270,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mText->setColor(mHudTextColor);
mText->setString(mHudTextString);
}
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
if (rlv_handler_t::isEnabled())
{
mText->setObjectText(mHudTextString);
}
// [/RLVa:KB]
setChanged(MOVED | SILHOUETTE);
}
@@ -1648,10 +1654,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
coloru.mV[3] = 255 - coloru.mV[3];
mHudTextColor = LLColor4(coloru); //Cache for reset on debug infodisplay toggle.
if(mText->getDoFade()) //Fade is disabled when this is being overridden by debug text.
mText->setColor(mHudTextColor);
mText->setString(mHudTextString);
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f
if (rlv_handler_t::isEnabled())
{
mText->setColor(mHudTextColor);
mText->setString(mHudTextString);
mText->setObjectText(mHudTextString);
}
// [/RLVa:KB]
setChanged(TEXTURE);
}
else if(mText.notNull())

View File

@@ -162,6 +162,9 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
const LLPCode pcode,
LLViewerRegion* regionp) :
LLVOAvatar(id, pcode, regionp),
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
mAttachmentSignal(NULL),
// [/RLVa:KB]
mScreenp(NULL),
mLastRegionHandle(0),
mRegionCrossingCount(0),
@@ -1130,6 +1133,14 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
return NULL;
}
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
boost::signals2::connection LLVOAvatarSelf::setAttachmentCallback(const attachment_signal_t::slot_type& cb)
{
if (!mAttachmentSignal)
mAttachmentSignal = new attachment_signal_t();
return mAttachmentSignal->connect(cb);
}
// [/RLVa:KB]
// [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
LLViewerJointAttachment* LLVOAvatarSelf::getWornAttachmentPoint(const LLUUID& idItem) const
{
@@ -1185,6 +1196,10 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a
// NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject()
if (mAttachmentSignal)
{
(*mAttachmentSignal)(viewer_object, attachment, ACTION_ATTACH);
}
if (rlv_handler_t::isEnabled())
{
RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment);
@@ -1213,16 +1228,24 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
// NOTE: RLVa event handlers should be invoked *before* LLVOAvatar::detachObject() calls LLViewerJointAttachment::removeObject()
if (rlv_handler_t::isEnabled())
{
for (attachment_map_t::const_iterator itAttachPt = mAttachmentPoints.begin(); itAttachPt != mAttachmentPoints.end(); ++itAttachPt)
{
const LLViewerJointAttachment* pAttachPt = itAttachPt->second;
if (pAttachPt->isObjectAttached(viewer_object))
{
RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt);
gRlvHandler.onDetach(viewer_object, pAttachPt);
if (rlv_handler_t::isEnabled())
{
RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt);
gRlvHandler.onDetach(viewer_object, pAttachPt);
}
if (mAttachmentSignal)
{
(*mAttachmentSignal)(viewer_object, pAttachPt, ACTION_DETACH);
}
}
break;
}
}
// [/RLVa:KB]
@@ -3171,6 +3194,22 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)
apr_file_printf( file, "\n</wearable_info>\n" );
}
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
LLVector3 LLVOAvatarSelf::getAvatarOffset() /*const*/
{
if(isUsingServerBakes())
return LLAvatarAppearance::getAvatarOffset();
else
{
static LLCachedControl<F32> x_off("AscentAvatarXModifier");
static LLCachedControl<F32> y_off("AscentAvatarYModifier");
static LLCachedControl<F32> z_off("AscentAvatarZModifier");
return LLVector3(x_off,y_off,z_off+RlvSettings::getAvatarOffsetZ());
}
}
// [/RLVa:KB]
// static
void LLVOAvatarSelf::onChangeSelfInvisible(bool invisible)
{

View File

@@ -318,9 +318,17 @@ public:
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
enum EAttachAction { ACTION_ATTACH, ACTION_DETACH };
typedef boost::signals2::signal<void (LLViewerObject*, const LLViewerJointAttachment*, EAttachAction)> attachment_signal_t;
boost::signals2::connection setAttachmentCallback(const attachment_signal_t::slot_type& cb);
// [/RLVa:KB]
private:
// Track attachments that have been requested but have not arrived yet.
mutable std::map<LLUUID,LLTimer> mAttachmentRequests;
// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
attachment_signal_t* mAttachmentSignal;
// [/RLVa:KB]
//--------------------------------------------------------------------
// HUDs
@@ -347,6 +355,11 @@ public:
public:
bool sendAppearanceMessage(LLMessageSystem *mesgsys) const;
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
protected:
/*virtual*/ LLVector3 getAvatarOffset() /*const*/;
// [/RLVa:KB]
/** Appearance
** **
*******************************************************************************/

View File

@@ -29,6 +29,8 @@
#include "llvoavatar.h"
#include "llworld.h"
#include "../lscript/lscript_byteformat.h" //Need LSCRIPTRunTimePermissionBits and SCRIPT_PERMISSION_*
#include "rlvcommon.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
@@ -296,6 +298,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet)
return "unset";
case RLV_RET_SUCCESS_DUPLICATE:
return "duplicate";
case RLV_RET_SUCCESS_DELAYED:
return "delayed";
case RLV_RET_FAILED_SYNTAX:
return "syntax error";
case RLV_RET_FAILED_OPTION:
@@ -414,6 +418,28 @@ void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy)
}
}
// Checked: 2012-08-19 (RLVa-1.4.7)
void RlvUtil::filterScriptQuestions(S32& nQuestions, LLSD& sdPayload)
{
// Check SCRIPT_PERMISSION_ATTACH
if ( (!gRlvAttachmentLocks.canAttach()) && (LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH] & nQuestions) )
{
// Notify the user that we blocked it since they're not allowed to wear any new attachments
sdPayload["rlv_blocked"] = RLV_STRING_BLOCKED_PERMATTACH;
nQuestions &= ~LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH];
}
// Check SCRIPT_PERMISSION_TELEPORT
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) && (LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT] & nQuestions) )
{
// Notify the user that we blocked it since they're not allowed to teleport
sdPayload["rlv_blocked"] = RLV_STRING_BLOCKED_PERMTELEPORT;
nQuestions &= ~LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT];
}
sdPayload["questions"] = nQuestions;
}
// Checked: 2010-08-29 (RLVa-1.2.1c) | Added: RLVa-1.2.1c
void RlvUtil::forceTp(const LLVector3d& posDest)
{
@@ -582,14 +608,23 @@ bool RlvEnableIfNot::handleEvent(LLPointer<LLEvent>, const LLSD& userdata)
// Selection functors
//
// Checked: 2010-04-11 (RLVa-1.2.0b) | Modified: RLVa-0.2.0g
// Checked: 2011-05-28 (RLVa-1.4.6) | Modified: RLVa-1.4.0
bool rlvCanDeleteOrReturn(const LLViewerObject* pObj)
{
// Block if: @rez=n restricted and owned by us or a group *or* @unsit=n restricted and being sat on by us
return
( (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || ((!pObj->permYouOwner()) && (!pObj->permGroupOwner())) ) &&
( (!gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (!isAgentAvatarValid()) || (!pObj->getRootEdit()->isChild(gAgentAvatarp)) );
}
// Checked: 2011-05-28 (RLVa-1.4.6) | Modified: RLVa-1.4.0
bool rlvCanDeleteOrReturn()
{
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) )
{
struct RlvCanDeleteOrReturn : public LLSelectedObjectFunctor
{
/*virtual*/ bool apply(LLViewerObject* pObj) { return pObj->isReturnable(); }
/*virtual*/ bool apply(LLViewerObject* pObj) { return rlvCanDeleteOrReturn(pObj); }
} f;
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
return (hSel.notNull()) && (0 != hSel->getRootObjectCount()) && (hSel->applyToRootObjects(&f, false));
@@ -652,7 +687,7 @@ bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWea
}
// Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem)
bool rlvPredCanRemoveItem(const LLInventoryItem* pItem)
{
if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) )
{
@@ -673,7 +708,7 @@ bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem)
}
// Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem)
bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem)
{
return !rlvPredCanRemoveItem(pItem);
}

View File

@@ -157,6 +157,7 @@ public:
static void filterLocation(std::string& strUTF8Text); // @showloc
static void filterNames(std::string& strUTF8Text, bool fFilterLegacy = true); // @shownames
static void filterScriptQuestions(S32& nQuestions, LLSD& sdPayload);
static bool isForceTp() { return m_fForceTp; }
static void forceTp(const LLVector3d& posDest); // Ignores restrictions that might otherwise prevent tp'ing
@@ -210,6 +211,7 @@ class RlvEnableIfNot : public LLMemberListener<LLView>
//
bool rlvCanDeleteOrReturn();
bool rlvCanDeleteOrReturn(const LLViewerObject* pObj);
struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor
{
@@ -238,8 +240,8 @@ protected:
bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask);
bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask);
bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem);
bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem);
bool rlvPredCanRemoveItem(const LLInventoryItem* pItem);
bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem);
struct RlvPredCanWearItem
{

View File

@@ -253,7 +253,8 @@ enum ERlvCmdRet {
RLV_RET_SUCCESS = 0x0100, // Command executed succesfully
RLV_RET_SUCCESS_UNSET, // Command executed succesfully (RLV_TYPE_REMOVE for an unrestricted behaviour)
RLV_RET_SUCCESS_DUPLICATE, // Command executed succesfully (RLV_TYPE_ADD for an already restricted behaviour)
RLV_RET_FAILED = 0x0200, // Command failed (general failure)
RLV_RET_SUCCESS_DELAYED, // Command parsed valid but will execute at a later time
RLV_RET_FAILED = 0x0200, // Command failed (general failure)
RLV_RET_FAILED_SYNTAX, // Command failed (syntax error)
RLV_RET_FAILED_OPTION, // Command failed (invalid option)
RLV_RET_FAILED_PARAM, // Command failed (invalid param)
@@ -337,6 +338,7 @@ enum ERlvAttachGroupType
#define RLV_STRING_BLOCKED_GENERIC "blocked_generic"
#define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach"
#define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport"
#define RLV_STRING_BLOCKED_RECVIM "blocked_recvim"
#define RLV_STRING_BLOCKED_RECVIM_REMOTE "blocked_recvim_remote"
#define RLV_STRING_BLOCKED_SENDIM "blocked_sendim"

View File

@@ -422,6 +422,10 @@ bool RlvHandler::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
gAgent.sendReliableMessage();
return true;
}
else
{
m_idAgentGroup = gAgent.getGroupID();
}
return false;
}
@@ -881,7 +885,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const
if ( (getCompositeInfo(idItem, &strComposite, &pFolder)) && (cstrItemType != strComposite) )
{
LLUUID idCompositeItem;
if ((type = LLViewerWearable::typeNameToType(strComposite)) != WT_INVALID)
if ((type = LLWearable::typeNameToType(strComposite)) != WT_INVALID)
{
idCompositeItem = gAgent.getWearableItem(type);
}
@@ -1252,14 +1256,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
RlvBehaviourNotifyHandler::getInstance()->removeNotify(rlvCmd.getObjectID(), nChannel, strFilter);
}
break;
case RLV_BHVR_SETGROUP: // @setgroup=n|y - Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b
{
VERIFY_OPTION_REF(strOption.empty());
// Save the currently active group UUID since we'll need it when the user joins (or creates) a new group
m_idAgentGroup = gAgent.getGroupID();
}
break;
case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n|y - Checked: 2010-03-27 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h
{
// There should be an option and it should specify a valid UUID
@@ -1273,8 +1269,8 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
// Clear/restore the object's hover text as needed
LLViewerObject* pObj = gObjectList.findObject(idException);
if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getPreFilteredText().empty()) )
pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getPreFilteredText());
if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) )
pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getObjectText());
}
break;
// The following block is only valid if there's no option
@@ -1312,6 +1308,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_TOUCHALL: // @touchall=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
case RLV_BHVR_TOUCHME: // @touchme=n|y - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
case RLV_BHVR_FLY: // @fly=n|y - Checked: 2010-03-02 (RLVa-1.2.0a)
case RLV_BHVR_SETGROUP: // @setgroup=n|y - Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b
case RLV_BHVR_ALWAYSRUN: // @alwaysrun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
case RLV_BHVR_TEMPRUN: // @temprun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
case RLV_BHVR_UNSIT: // @unsit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
@@ -1641,15 +1638,9 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_ATTACHALLTHISOVER:
case RLV_BHVR_DETACHALLTHIS:
{
RlvCommandOptionGetPath rlvGetPathOption(rlvCmd);
RlvCommandOptionGetPath rlvGetPathOption(rlvCmd, boost::bind(&RlvHandler::onForceWearCallback, this, _1, rlvCmd.getBehaviourType()));
VERIFY_OPTION(rlvGetPathOption.isValid());
LLInventoryModel::cat_array_t folders;
if (RlvInventory::instance().getPath(rlvGetPathOption.getItemIDs(), folders))
{
for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
onForceWear(folders.get(idxFolder), rlvCmd.getBehaviourType());
}
eRet = (!rlvGetPathOption.isCallback()) ? RLV_RET_SUCCESS : RLV_RET_SUCCESS_DELAYED;
}
break;
case RLV_BHVR_DETACHME: // @detachme=force - Checked: 2010-09-04 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
@@ -1727,10 +1718,15 @@ ERlvCmdRet RlvHandler::onForceRemOutfit(const RlvCommand& rlvCmd) const
// Checked: 2011-07-23 (RLVa-1.4.1a) | Modified: RLVa-1.4.1a
ERlvCmdRet RlvHandler::onForceGroup(const RlvCommand& rlvCmd) const
{
if (hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID()))
{
return RLV_RET_FAILED_LOCK;
}
LLUUID idGroup; bool fValid = false;
if (idGroup.set(rlvCmd.getOption()))
{
fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup));
fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true));
}
else
{
@@ -1742,16 +1738,15 @@ ERlvCmdRet RlvHandler::onForceGroup(const RlvCommand& rlvCmd) const
if (fValid)
{
if (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))
{
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ActivateGroup);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_GroupID, idGroup);
gAgent.sendReliableMessage();
}
m_idAgentGroup = idGroup;
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ActivateGroup);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_GroupID, idGroup);
gAgent.sendReliableMessage();
}
return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION;
@@ -1818,6 +1813,20 @@ ERlvCmdRet RlvHandler::onForceWear(const LLViewerInventoryCategory* pFolder, ERl
return RLV_RET_SUCCESS;
}
void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, ERlvBehaviour eBhvr) const
{
LLInventoryModel::cat_array_t folders;
if (RlvInventory::instance().getPath(idItems, folders))
{
for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
onForceWear(folders.get(idxFolder), eBhvr);
// If we're not executing a command then we're a delayed callback and need to manually call done()
if ( (!getCurrentCommand()) && (RlvForceWear::instanceExists()) )
RlvForceWear::instance().done();
}
}
// ============================================================================
// Command handlers (RLV_TYPE_REPLY)
//

View File

@@ -84,6 +84,7 @@ public:
*/
public:
// Accessors
const LLUUID& getAgentGroup() const { return m_idAgentGroup; } // @setgroup
bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto
void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto
const LLVector3d& getSitSource() const { return m_posSitSource; } // @standtp
@@ -169,6 +170,7 @@ protected:
ERlvCmdRet onForceGroup(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceSit(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceWear(const LLViewerInventoryCategory* pFolder, ERlvBehaviour eBhvr) const;
void onForceWearCallback(const uuid_vec_t& idItems, ERlvBehaviour eBhvr) const;
// Command handlers (RLV_TYPE_REPLY)
ERlvCmdRet processReplyCommand(const RlvCommand& rlvCmd) const;
ERlvCmdRet onFindFolder(const RlvCommand& rlvCmd, std::string& strReply) const;
@@ -208,7 +210,7 @@ protected:
bool m_fCanCancelTp; // @accepttp=n and @tpto=force
mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const)
LLUUID m_idAgentGroup; // @setgroup=n
mutable LLUUID m_idAgentGroup; // @setgroup=n
friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete
friend class RlvGCTimer; // Timer clear its own point at destruction

View File

@@ -210,13 +210,56 @@ RlvCommandOptionGeneric::RlvCommandOptionGeneric(const std::string& strOption)
m_fValid = true;
}
// Checked: 2012-07-28 (RLVa-1.4.7)
class RlvCommandOptionGetPathCallback
{
public:
RlvCommandOptionGetPathCallback(const LLUUID& idAttachObj, RlvCommandOptionGetPath::getpath_callback_t cb)
: mObjectId(idAttachObj), mCallback(cb)
{
if (isAgentAvatarValid())
mAttachmentConnection = gAgentAvatarp->setAttachmentCallback(boost::bind(&RlvCommandOptionGetPathCallback::onAttachment, this, _1, _3));
gIdleCallbacks.addFunction(&onIdle, this);
}
~RlvCommandOptionGetPathCallback()
{
if (mAttachmentConnection.connected())
mAttachmentConnection.disconnect();
gIdleCallbacks.deleteFunction(&onIdle, this);
}
void onAttachment(LLViewerObject* pAttachObj, LLVOAvatarSelf::EAttachAction eAction)
{
if ( (LLVOAvatarSelf::ACTION_ATTACH == eAction) && (pAttachObj->getID() == mObjectId) )
{
uuid_vec_t idItems(1, pAttachObj->getAttachmentItemID());
mCallback(idItems);
delete this;
}
}
static void onIdle(void* pData)
{
RlvCommandOptionGetPathCallback* pInstance = reinterpret_cast<RlvCommandOptionGetPathCallback*>(pData);
if (pInstance->mExpirationTimer.getElapsedTimeF32() > 30.0f)
delete pInstance;
}
protected:
LLUUID mObjectId;
RlvCommandOptionGetPath::getpath_callback_t mCallback;
boost::signals2::connection mAttachmentConnection;
LLFrameTimer mExpirationTimer;
};
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd)
RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd, getpath_callback_t cb)
: m_fCallback(false)
{
m_fValid = true; // Assume the option will be a valid one until we find out otherwise
// @getpath[:<option>]=<channel> => <option> is transformed to a list of inventory item UUIDs to get the path of
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
if (rlvCmdOption.isWearableType()) // <option> can be a clothing layer
{
@@ -229,12 +272,27 @@ RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd)
else if (rlvCmdOption.isEmpty()) // ... or it can be empty (in which case we act on the object that issued the command)
{
const LLViewerObject* pObj = gObjectList.findObject(rlvCmd.getObjectID());
if ( (pObj) || (pObj->isAttachment()) )
m_idItems.push_back(pObj->getAttachmentItemID());
if (pObj)
{
if (pObj->isAttachment())
m_idItems.push_back(pObj->getAttachmentItemID());
}
else if (!cb.empty())
{
new RlvCommandOptionGetPathCallback(rlvCmd.getObjectID(), cb);
m_fCallback = true;
return;
}
}
else // ... but anything else isn't a valid option
{
m_fValid = false;
return;
}
if (!cb.empty())
{
cb(getItemIDs());
}
}
@@ -438,6 +496,9 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
RlvWearableItemCollector f(pFolder, eAction, eFlags);
gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE);
// TRUE if we've already encountered this LLWearableType::EType (used only on wear actions and only for AT_CLOTHING)
bool fSeenWType[LLWearableType::WT_COUNT] = { false };
EWearAction eCurAction = eAction;
for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
{
@@ -451,6 +512,8 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
// Each folder can specify its own EWearAction override
if (isWearAction(eAction))
eCurAction = f.getWearAction(pRlvItem->getParentUUID());
else
eCurAction = eAction;
// NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending)
// * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn
@@ -461,6 +524,10 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
case LLAssetType::AT_CLOTHING:
if (isWearAction(eAction))
{
// The first time we encounter any given clothing type we use 'eCurAction' (replace or add)
// The second time we encounter a given clothing type we'll always add (rather than replace the previous iteration)
eCurAction = (!fSeenWType[pItem->getWearableType()]) ? eCurAction : ACTION_WEAR_ADD;
ERlvWearMask eWearMask = gRlvWearableLocks.canWear(pRlvItem);
if ( ((ACTION_WEAR_REPLACE == eCurAction) && (eWearMask & RLV_WEAR_REPLACE)) ||
((ACTION_WEAR_ADD == eCurAction) && (eWearMask & RLV_WEAR_ADD)) )
@@ -468,6 +535,7 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
// The check for whether we're replacing a currently worn composite item happens in onWearableArrived()
if (!isAddWearable(pItem))
addWearable(pRlvItem, eCurAction);
fSeenWType[pItem->getWearableType()] = true;
}
}
else
@@ -699,19 +767,21 @@ bool RlvForceWear::isStrippable(const LLInventoryItem* pItem)
}
LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
while ( (pFolder) && (gInventory.getRootFolderID() != pFolder->getParentUUID()) )
while (pFolder)
{
if (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP))
return false;
// If the item's parent is a folded folder then we need to check its parent as well
pFolder =
(RlvInventory::isFoldedFolder(pFolder, true)) ? gInventory.getCategory(pFolder->getParentUUID()) : NULL;
if ( (gInventory.getRootFolderID() != pFolder->getParentUUID()) && (RlvInventory::isFoldedFolder(pFolder, true)) )
pFolder = gInventory.getCategory(pFolder->getParentUUID());
else
pFolder = NULL;
}
}
return true;
}
// Checked: 2010-08-30 (RLVa-1.1.3b) | Modified: RLVa-1.2.1c
// Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
void RlvForceWear::addAttachment(const LLViewerInventoryItem* pItem, EWearAction eAction)
{
// Remove it from 'm_remAttachments' if it's queued for detaching
@@ -778,10 +848,12 @@ void RlvForceWear::remAttachment(const LLViewerObject* pAttachObj)
// Add it to 'm_remAttachments' if it's not already there
if (!isRemAttachment(pAttachObj))
m_remAttachments.push_back(pAttachObj);
{
m_remAttachments.push_back(const_cast<LLViewerObject*>(pAttachObj));
}
}
// Checked: 2010-08-30 (RLVa-1.1.3b) | Modified: RLVa-1.2.1c
// Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
void RlvForceWear::addWearable(const LLViewerInventoryItem* pItem, EWearAction eAction)
{
const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(pItem->getLinkedUUID());
@@ -868,19 +940,9 @@ void RlvForceWear::done()
if (m_remAttachments.size())
{
// Don't bother with COF if all we're doing is detaching some attachments (keeps people from rebaking on every @remattach=force)
gMessageSystem->newMessage("ObjectDetach");
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
for (std::list<const LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin();
itAttachObj != m_remAttachments.end(); ++itAttachObj)
{
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*itAttachObj)->getLocalID());
}
gMessageSystem->sendReliable(gAgent.getRegionHost());
LLAgentWearables::userRemoveMultipleAttachments(m_remAttachments);
for (std::list<const LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin();
for (std::vector<LLViewerObject*>::const_iterator itAttachObj = m_remAttachments.begin();
itAttachObj != m_remAttachments.end(); ++itAttachObj)
{
pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID());
@@ -986,7 +1048,7 @@ void RlvBehaviourNotifyHandler::sendNotification(const std::string& strText, con
for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = pThis->m_Notifications.begin();
itNotify != pThis->m_Notifications.end(); ++itNotify)
{
if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strText.find(itNotify->second.strFilter)) )
if ( (itNotify->second.strFilter.empty()) || (boost::icontains(strText, itNotify->second.strFilter)) )
RlvUtil::sendChatReply(itNotify->second.nChannel, "/" + strText + strSuffix);
}
}
@@ -1022,49 +1084,6 @@ void RlvBehaviourNotifyHandler::onReattach(const LLViewerJointAttachment* pAttac
sendNotification(llformat("reattached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str()));
}
// ============================================================================
// RlvWLSnapshot
//
// Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h
#if 0
void RlvWLSnapshot::restoreSnapshot(const RlvWLSnapshot* pWLSnapshot)
{
LLWLParamManager* pWLParams = LLWLParamManager::getInstance();
if ( (pWLSnapshot) && (pWLParams) )
{
if (pWLSnapshot->fIsRunning)
{
pWLParams->mAnimator.activate(pWLSnapshot->fUseLindenTime ? LLWLAnimator::TIME_LINDEN : LLWLAnimator::TIME_CUSTOM);
}
pWLParams->mCurParams = pWLSnapshot->WLParams;
pWLParams->propagateParameters();
}
}
// Checked: 2009-09-16 (RLVa-1.0.3c) | Modified: RLVa-1.0.3c
RlvWLSnapshot* RlvWLSnapshot::takeSnapshot()
{
// HACK: see RlvExtGetSet::onGetEnv
if (!LLFloaterWindLight::isOpen())
{
LLFloaterWindLight::instance()->close();
LLFloaterWindLight::instance()->syncMenu();
}
RlvWLSnapshot* pWLSnapshot = NULL;
LLWLParamManager* pWLParams = LLWLParamManager::getInstance();
if (pWLParams)
{
pWLSnapshot = new RlvWLSnapshot();
pWLSnapshot->fIsRunning = pWLParams->mAnimator.getIsRunning();
pWLSnapshot->fUseLindenTime = pWLParams->mAnimator.getUseLindenTime();
pWLSnapshot->WLParams = pWLParams->mCurParams;
}
return pWLSnapshot;
}
#endif
// =========================================================================
// Various helper classes/timers/functors
//

View File

@@ -139,8 +139,10 @@ protected:
struct RlvCommandOptionGetPath : public RlvCommandOption
{
RlvCommandOptionGetPath(const RlvCommand& rlvCmd);
typedef boost::function<void(const uuid_vec_t&)> getpath_callback_t;
RlvCommandOptionGetPath(const RlvCommand& rlvCmd, getpath_callback_t cb = NULL);
bool isCallback() const { return m_fCallback; }
/*virtual*/ bool isEmpty() const { return m_idItems.empty(); }
const uuid_vec_t& getItemIDs() const { return m_idItems; }
@@ -148,6 +150,7 @@ struct RlvCommandOptionGetPath : public RlvCommandOption
static bool getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear = true);
protected:
bool m_fCallback; // TRUE if a callback is schedueled
uuid_vec_t m_idItems;
};
@@ -292,8 +295,8 @@ protected:
typedef std::map<S32, LLInventoryModel::item_array_t> addattachments_map_t;
addattachments_map_t m_addAttachments;
LLInventoryModel::item_array_t m_addGestures;
std::list<const LLViewerObject*> m_remAttachments;
std::list<const LLViewerWearable*> m_remWearables;
std::vector<LLViewerObject*> m_remAttachments; // This should match the definition of LLAgentWearables::llvo_vec_t
std::list<const LLViewerWearable*> m_remWearables;
LLInventoryModel::item_array_t m_remGestures;
private:

View File

@@ -20,6 +20,7 @@
#include "llinventoryobserver.h"
#include "llstartup.h"
#include "llviewerfoldertype.h"
#include "llviewermessage.h"
#include "llviewerobject.h"
#include "llvoavatarself.h"
@@ -379,6 +380,27 @@ S32 RlvInventory::getDirectDescendentsItemCount(const LLInventoryCategory* pFold
return cntType;
}
// Checked: 2012-11-28 (RLVa-1.4.8)
bool RlvInventory::isGiveToRLVOffer(const LLOfferInfo& offerInfo)
{
if ( (!RlvSettings::getForbidGiveToRLV()) && (RlvInventory::instance().getSharedRoot()) )
{
if (offerInfo.mFromObject)
{
return
(IM_TASK_INVENTORY_OFFERED == offerInfo.mIM) &&
(LLAssetType::AT_CATEGORY == offerInfo.mType) && (offerInfo.mDesc.find(RLV_PUTINV_PREFIX) == 1);
}
else
{
return
(IM_INVENTORY_OFFERED == offerInfo.mIM) &&
(LLAssetType::AT_CATEGORY == offerInfo.mType) && (offerInfo.mDesc.find(RLV_PUTINV_PREFIX) == 0);
}
}
return false;
}
// ============================================================================
// RlvRenameOnWearObserver member functions
//
@@ -404,7 +426,7 @@ void RlvRenameOnWearObserver::doneIdle()
}
const LLViewerJointAttachment* pAttachPt = NULL; S32 idxAttachPt = 0;
RLV_ASSERT(mComplete.size() > 0); // Catch instances where we forgot to call startFetch()
//RLV_ASSERT(mComplete.size() > 0); // Catch instances where we forgot to call startFetch()
for (uuid_vec_t::const_iterator itItem = mComplete.begin(); itItem != mComplete.end(); ++itItem)
{
const LLUUID& idAttachItem = *itItem;

View File

@@ -26,6 +26,8 @@
#include "rlvhelper.h"
#include "rlvlocks.h"
struct LLOfferInfo;
// ============================================================================
// RlvInventory class declaration
//
@@ -61,6 +63,8 @@ public:
std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const;
// Returns TRUE if the supplied folder is a descendent of the #RLV folder
bool isSharedFolder(const LLUUID& idFolder);
// Returns TRUE if the inventory offer is a "give to #RLV" offer
bool isGiveToRLVOffer(const LLOfferInfo& offerInfo);
/*
* Inventory fetching

View File

@@ -361,9 +361,14 @@ protected:
/*
* Member variables
*/
public:
typedef std::list<const folderlock_descr_t*> folderlock_list_t;
// Accessors for RlvFloaterLocks
const folderlock_list_t& getFolderLocks() { return m_FolderLocks; }
const uuid_vec_t& getAttachmentLookups() { return m_LockedAttachmentRem; }
const uuid_vec_t& getWearableLookups() { return m_LockedWearableRem; }
protected:
// Map of folder locks (idRlvObj -> lockDescr)
typedef std::list<const folderlock_descr_t*> folderlock_list_t;
folderlock_list_t m_FolderLocks; // List of add and remove locked folder descriptions
S32 m_cntLockAdd; // Number of RLV_LOCK_ADD locked folders in m_FolderLocks
S32 m_cntLockRem; // Number of RLV_LOCK_REMOVE locked folders in m_FolderLocks

View File

@@ -3922,6 +3922,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="inventory_item_offered-im">
Inventory item offered
</string>
<string name="inventory_item_offered_rlv">
Inventory item offered to [NAME]
</string>
<string name="only_user_message">