Merge remote-tracking branch 'shyotl/sunshine'

Conflicts:
	indra/llappearance/llavatarappearance.cpp
	indra/newview/character/avatar_lad.xml
	indra/newview/llagent.cpp
This commit is contained in:
Latif Khalifa
2013-03-26 23:54:36 +01:00
36 changed files with 657 additions and 404 deletions

View File

@@ -463,9 +463,12 @@ void LLAvatarAppearance::computeBodySize()
LLVector3 foot = mFootLeftp->getPosition();
F32 old_offset = mAvatarOffset.mV[VZ];
LLVector3 old_offset = mAvatarOffset;
mAvatarOffset.mV[VZ] = getVisualParamWeight(11001);
// [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] -
@@ -486,16 +489,23 @@ void LLAvatarAppearance::computeBodySize()
new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
mAvatarOffset.mV[VX] = 0.0f;
mAvatarOffset.mV[VY] = 0.0f;
//mAvatarOffset.mV[VX] = 0.0f;
//mAvatarOffset.mV[VY] = 0.0f;
if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
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);

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

@@ -172,6 +172,9 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
mHideFromSettingsEditor(hidefromsettingseditor),
mCommitSignal(new commit_signal_t),
mValidateSignal(new validate_signal_t),
#ifdef PROF_CTRL_CALLS
mLookupCount(0),
#endif //PROF_CTRL_CALLS
mIsCOA(IsCOA),
mIsCOAParent(false),
mCOAConnectedVar(NULL)
@@ -339,29 +342,16 @@ LLSD LLControlVariable::getSaveValue() const
{
//The first level of the stack is default
//We assume that the second level is user preferences that should be saved
if(mValues.size() > 1) return mValues[1];
if(mValues.size() > 1) return mValues[1];
return mValues[0];
}
#if PROF_CTRL_CALLS
std::vector<std::pair<std::string, U32>> gSettingsCallMap;
static update_gSettingsCallMap(ctrl_name_table_t::const_iterator const& iter)
#ifdef PROF_CTRL_CALLS
void LLControlGroup::updateLookupMap(ctrl_name_table_t::const_iterator iter) const
{
if(iter != mNameTable.end())
if(iter != mNameTable.end() && iter->second.notNull())
{
std::vector<std::pair<std::string, U32>>::iterator iter2 = gSettingsCallMap.begin();
std::vector<std::pair<std::string, U32>>::iterator end = gSettingsCallMap.end();
for(;iter2!=end;iter2++)
{
if(iter2->first==name)
{
iter2->second = iter2->second + 1;
break;
}
}
if(iter2 == gSettingsCallMap.end())
gSettingsCallMap.push_back(std::pair<std::string, U32>(name.c_str(),1));
iter->second.get()->mLookupCount++;
}
}
#endif //PROF_CTRL_CALLS
@@ -369,8 +359,8 @@ static update_gSettingsCallMap(ctrl_name_table_t::const_iterator const& iter)
LLControlVariable* LLControlGroup::getControl(std::string const& name)
{
ctrl_name_table_t::iterator iter = mNameTable.find(name);
#if PROF_CTRL_CALLS
update_gSettingsCallMap(iter);
#ifdef PROF_CTRL_CALLS
updateLookupMap(iter);
#endif //PROF_CTRL_CALLS
if(iter != mNameTable.end())
return iter->second->getCOAActive();
@@ -381,8 +371,8 @@ LLControlVariable* LLControlGroup::getControl(std::string const& name)
LLControlVariable const* LLControlGroup::getControl(std::string const& name) const
{
ctrl_name_table_t::const_iterator iter = mNameTable.find(name);
#if PROF_CTRL_CALLS
update_gSettingsCallMap(iter);
#ifdef PROF_CTRL_CALLS
updateLookupMap(iter);
#endif //PROF_CTRL_CALLS
if(iter != mNameTable.end())
return iter->second->getCOAActive();

View File

@@ -69,6 +69,10 @@
# endif
#endif
#if LL_RELEASE_WITH_DEBUG_INFO
#define PROF_CTRL_CALLS
#endif //LL_RELEASE_WITH_DEBUG_INFO
class LLVector3;
class LLVector3d;
class LLColor3;
@@ -179,6 +183,10 @@ public:
mValidateSignal = pConnect->mValidateSignal;
}
}
#ifdef PROF_CTRL_CALLS
public:
U32 mLookupCount;
#endif //PROF_CTRL_CALLS
private:
LLSD getComparableValue(const LLSD& value);
bool llsd_compare(const LLSD& a, const LLSD & b);
@@ -347,6 +355,10 @@ public:
void connectCOAVars(LLControlGroup &OtherGroup);
void updateCOASetting(bool coa_enabled);
bool handleCOASettingChange(const LLSD& newvalue);
#ifdef PROF_CTRL_CALLS
void updateLookupMap(ctrl_name_table_t::const_iterator iter) const;
#endif //PROF_CTRL_CALLS
};

View File

@@ -840,7 +840,7 @@
<param_skeleton />
</param>
</skeleton>
</skeleton>
<mesh
type="hairMesh"

View File

@@ -200,13 +200,24 @@ void invrepair()
gInventory.collectDescendents(gInventory.getRootFolderID(),cats,items,FALSE);//,objectnamematches);
}
#if PROF_CTRL_CALLS
extern std::vector<std::pair<std::string, U32>> gSettingsCallMap;
bool stort_calls(const std::pair<std::string, U32>& left, const std::pair<std::string, U32>& right)
#ifdef PROF_CTRL_CALLS
bool sort_calls(const std::pair<std::string, U32>& left, const std::pair<std::string, U32>& right)
{
return left.second < right.second;
return left.second > right.second;
}
//Structure to be passed into LLControlGroup::applyToAll.
// Doesn't actually modify control group, but rather uses the 'apply'
// vfn to add each variable in the group to a list. This essentially
// allows us to copy the private variable list without touching the controlgroup
// class.
struct ProfCtrlListAccum : public LLControlGroup::ApplyFunctor
{
virtual void apply(const std::string& name, LLControlVariable* control)
{
mVariableList.push_back(std::make_pair(name,control->mLookupCount));
}
std::vector<std::pair<std::string, U32> > mVariableList;
};
#endif //PROF_CTRL_CALLS
bool cmd_line_chat(std::string revised_text, EChatType type)
{
@@ -445,13 +456,23 @@ bool cmd_line_chat(std::string revised_text, EChatType type)
{
invrepair();
}
#if PROF_CTRL_CALLS
#ifdef PROF_CTRL_CALLS
else if(command == "dumpcalls")
{
llinfos << "gSavedSettings lookup count (" << gFrameCount << "frames)" << llendl;
std::sort(gSettingsCallMap.begin(),gSettingsCallMap.end(),stort_calls);
for(U32 i = 0;i<gSettingsCallMap.size();i++)
llinfos << gSettingsCallMap[i].first << " : " << gSettingsCallMap[i].second << " " << ((float)gSettingsCallMap[i].second / (float)gFrameCount) << "c/f" << llendl;
LLControlGroup::key_iter it = LLControlGroup::beginKeys();
LLControlGroup::key_iter end = LLControlGroup::endKeys();
for(;it!=end;++it)
{
ProfCtrlListAccum list;
LLControlGroup::getInstance(*it)->applyToAll(&list);
std::sort(list.mVariableList.begin(),list.mVariableList.end(),sort_calls);
LL_INFOS("") << *it << ": lookup count (" << gFrameCount << "frames)" << LL_ENDL;
for(U32 i = 0;i<list.mVariableList.size();i++)
{
if(list.mVariableList[i].second)
LL_INFOS("") << " " << list.mVariableList[i].first << ": " << list.mVariableList[i].second << " lookups, " << ((float)list.mVariableList[i].second / (float)gFrameCount) << "l/f\n" << LL_ENDL;
}
}
return false;
}
#endif //PROF_CTRL_CALLS

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

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

@@ -567,9 +567,10 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
{
BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
static const LLCachedControl<bool> disable_camera_constraints("DisableCameraConstraints");
if (!mFocusObject || mFocusObject->isDead() ||
mFocusObject->isMesh() ||
gSavedSettings.getBOOL("DisableCameraConstraints"))
disable_camera_constraints)
{
obj_min_distance = 0.f;
return TRUE;
@@ -731,6 +732,7 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
F32 LLAgentCamera::getCameraZoomFraction()
{
static const LLCachedControl<bool> ascent_disable_min_zoom_dist("AscentDisableMinZoomDist");
// 0.f -> camera zoomed all the way out
// 1.f -> camera zoomed all the way in
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
@@ -739,7 +741,7 @@ F32 LLAgentCamera::getCameraZoomFraction()
// already [0,1]
return mHUDTargetZoom;
}
else if (gSavedSettings.getBOOL("AscentDisableMinZoomDist"))
else if (ascent_disable_min_zoom_dist)
{
return mCameraZoomFraction;
}
@@ -783,15 +785,15 @@ F32 LLAgentCamera::getCameraZoomFraction()
void LLAgentCamera::setCameraZoomFraction(F32 fraction)
{
static const LLCachedControl<bool> ascent_disable_min_zoom_dist("AscentDisableMinZoomDist");
// 0.f -> camera zoomed all the way out
// 1.f -> camera zoomed all the way in
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
BOOL disable_min = gSavedSettings.getBOOL("AscentDisableMinZoomDist");
if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
{
mHUDTargetZoom = fraction;
}
else if (mFocusOnAvatar && cameraThirdPerson() && !disable_min)
else if (mFocusOnAvatar && cameraThirdPerson() && !ascent_disable_min_zoom_dist)
{
mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
}
@@ -809,7 +811,7 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
// LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
// MAX_CAMERA_DISTANCE_FROM_AGENT);
if (!disable_min)
if (!ascent_disable_min_zoom_dist)
{
if (mFocusObject.notNull())
{
@@ -914,7 +916,9 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
F32 current_distance = (F32)camera_offset_unit.normalize();
F32 new_distance = current_distance * fraction;
if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist"))
static const LLCachedControl<bool> ascent_disable_min_zoom_dist("AscentDisableMinZoomDist");
if (!ascent_disable_min_zoom_dist)
{
if (mFocusObject)
{
@@ -968,7 +972,8 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
{
if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
{
F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
static const LLCachedControl<F32> camera_offset_scale("CameraOffsetScale");
F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * camera_offset_scale);
mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
@@ -1143,8 +1148,12 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
F32 y_from_center =
((F32) mouse_y / (F32) gViewerWindow->getWorldViewHeightScaled() ) - 0.5f;
frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
static const LLCachedControl<F32> yaw_from_mouse_position("YawFromMousePosition");
static const LLCachedControl<F32> pitch_from_mouse_position("PitchFromMousePosition");
frameCamera.yaw( - x_from_center * yaw_from_mouse_position * DEG_TO_RAD);
frameCamera.pitch( - y_from_center * pitch_from_mouse_position * DEG_TO_RAD);
lookAtType = LOOKAT_TARGET_FREELOOK;
}
@@ -1381,7 +1390,8 @@ void LLAgentCamera::updateCamera()
{
const F32 SMOOTHING_HALF_LIFE = 0.02f;
F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
static const LLCachedControl<F32> camera_position_smoothing("CameraPositionSmoothing");
F32 smoothing = LLCriticalDamp::getInterpolant(camera_position_smoothing * SMOOTHING_HALF_LIFE, FALSE);
if (!mFocusObject) // we differentiate on avatar mode
{
@@ -1609,7 +1619,8 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
{
LLDrawable* drawablep = mFocusObject->mDrawable;
if (gSavedSettings.getBOOL("TrackFocusObject") && drawablep)
static const LLCachedControl<bool> track_focus_object("TrackFocusObject");
if (track_focus_object && drawablep)
{
if (drawablep->isActive() && !mFocusObject->isAvatar())
{
@@ -1715,7 +1726,8 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor()
{
// don't FOV zoom on mostly transparent objects
F32 obj_min_dist = 0.f;
if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist"))
static const LLCachedControl<bool> ascent_disable_min_zoom_dist("AscentDisableMinZoomDist");
if (!ascent_disable_min_zoom_dist)
calcCameraMinDistance(obj_min_dist);
F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
@@ -1804,7 +1816,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
else
{
local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
static const LLCachedControl<F32> camera_offset_scale("CameraOffsetScale");
local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * camera_offset_scale;
// are we sitting down?
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
@@ -1911,7 +1924,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
else
{
target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
static const LLCachedControl<F32> dynamic_camera_strength("DynamicCameraStrength");
target_lag = vel * dynamic_camera_strength / 30.f;
}
mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
@@ -1946,7 +1960,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
camera_position_global = focusPosGlobal + mCameraFocusOffset;
}
if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
static const LLCachedControl<bool> disable_camera_constraints("DisableCameraConstraints");
if (!disable_camera_constraints && !gAgent.isGodlike())
{
LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
bool constrain = true;
@@ -2042,10 +2057,11 @@ void LLAgentCamera::handleScrollWheel(S32 clicks)
{
F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
static const LLCachedControl<F32> camera_offset_scale("CameraOffsetScale");
F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * camera_offset_scale);
current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * camera_offset_scale);
}
else
{
@@ -2067,7 +2083,8 @@ F32 LLAgentCamera::getCameraMinOffGround()
}
else
{
if (gSavedSettings.getBOOL("DisableCameraConstraints"))
static const LLCachedControl<bool> disable_camera_constraints("DisableCameraConstraints");
if (disable_camera_constraints)
{
return -1000.f;
}

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);
@@ -1332,12 +1322,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++)
{
@@ -1357,51 +1341,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);
}
@@ -1446,7 +1389,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()))
@@ -1494,7 +1437,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)
@@ -1667,8 +1610,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:
@@ -1735,8 +1678,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);
}
@@ -1750,12 +1693,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))
@@ -1763,12 +1706,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
{
@@ -1799,10 +1742,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

@@ -201,6 +201,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
@@ -4436,7 +4439,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
@@ -4615,6 +4619,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

@@ -687,17 +687,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

@@ -1477,6 +1477,9 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
bool busy=FALSE;
// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Added: RLVa-1.2.1e
bool fRlvNotifyAccepted = false;
// [/RLVa:KB]
switch(button)
{
case IOR_ACCEPT:
@@ -1492,11 +1495,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
if ( (rlv_handler_t::isEnabled()) &&
(IM_TASK_INVENTORY_OFFERED == mIM) && (LLAssetType::AT_CATEGORY == mType) && (mDesc.find(RLV_PUTINV_PREFIX) == 1) )
{
fRlvNotifyAccepted = true;
if (!RlvSettings::getForbidGiveToRLV())
{
const LLViewerInventoryCategory* pRlvRoot = RlvInventory::instance().getSharedRoot();
if (pRlvRoot)
{
fRlvNotifyAccepted = false; // "accepted_in_rlv" is sent from RlvGiveToRLVTaskOffer *after* we have the folder
mFolderID = pRlvRoot->getUUID();
RlvGiveToRLVTaskOffer* pOfferObserver = new RlvGiveToRLVTaskOffer(mTransactionID);
@@ -1513,6 +1518,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))
@@ -6508,12 +6522,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);
@@ -6521,7 +6529,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)");
@@ -6535,7 +6551,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

@@ -1269,6 +1269,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);
}
@@ -1649,10 +1655,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),
@@ -1119,6 +1122,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
{
@@ -1174,6 +1185,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);
@@ -1202,16 +1217,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]
@@ -3197,6 +3220,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

@@ -3981,6 +3981,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">