Merged with RLVa-1.3.1c

Kitty Barnett 2011-06-03 21:38:34 +02:00
commit 825d5bc58e
67 changed files with 7809 additions and 6759 deletions

View File

@ -158,3 +158,5 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
0000000000000000000000000000000000000000 DRTVWR-38_2.5.2-release
0000000000000000000000000000000000000000 2.5.2-release
8f16fc4647d4a97b02042094a213b1fdea5c9462 FSmerge-2.5.2
43cb7dc1804de1a25c0b2b3f0715584af1f8b470 RLVa-1.2.2
89532c8dfd5b6c29f1cb032665b44a74a52452e1 RLVa-1.3.0

View File

@ -794,6 +794,7 @@ Twisted Laws
STORM-844
STORM-643
STORM-954
STORM-1103
Vadim Bigbear
VWR-2681
Vector Hastings

View File

@ -883,6 +883,13 @@ std::string LLNotification::getLabel() const
return (mTemplatep ? label : "");
}
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
bool LLNotification::hasLabel() const
{
return !mTemplatep->mLabel.empty();
}
// [/SL:KB]
std::string LLNotification::getURL() const
{
if (!mTemplatep)

View File

@ -507,6 +507,10 @@ public:
return mTimestamp;
}
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
bool hasLabel() const;
// [/SL:KB]
std::string getType() const;
std::string getMessage() const;
std::string getLabel() const;

View File

@ -6426,6 +6426,17 @@
<key>Value</key>
<integer>305</integer>
</map>
<key>NotificationCanEmbedInIM</key>
<map>
<key>Comment</key>
<string>Controls notification panel embedding in IMs (0 = default, 1 = focused, 2 = never)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>NotificationToastLifeTime</key>
<map>
<key>Comment</key>
@ -9957,6 +9968,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>NearbyListShowMap</key>
<map>
<key>Comment</key>
<string>Show/hide map above nearby people list</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>NearbyListShowIcons</key>
<map>
<key>Comment</key>

View File

@ -77,8 +77,9 @@
#include "llwindow.h"
#include "llworld.h"
#include "llworldmap.h"
// [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvhelper.h"
// [/RLVa:KB]
#include "kcwlinterface.h"
@ -174,7 +175,10 @@ LLAgent::LLAgent() :
mDoubleTapRunMode(DOUBLETAP_NONE),
mbAlwaysRun(false),
mbRunning(false),
// mbRunning(false),
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
mbTempRun(false),
// [/RLVa:KB]
mbTeleportKeepsLookAt(false),
mAgentAccess(gSavedSettings),
@ -2689,7 +2693,36 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
sendReliableMessage();
}
void LLAgent::sendWalkRun(bool running)
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
void LLAgent::setAlwaysRun()
{
mbAlwaysRun = (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_ALWAYSRUN));
sendWalkRun();
}
void LLAgent::setTempRun()
{
mbTempRun = (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_TEMPRUN));
sendWalkRun();
}
void LLAgent::clearAlwaysRun()
{
mbAlwaysRun = false;
sendWalkRun();
}
void LLAgent::clearTempRun()
{
mbTempRun = false;
sendWalkRun();
}
// [/RLVa:KB]
//void LLAgent::sendWalkRun(bool running)
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
void LLAgent::sendWalkRun()
// [/RLVa:KB]
{
LLMessageSystem* msgsys = gMessageSystem;
if (msgsys)
@ -2698,7 +2731,10 @@ void LLAgent::sendWalkRun(bool running)
msgsys->nextBlockFast(_PREHASH_AgentData);
msgsys->addUUIDFast(_PREHASH_AgentID, getID());
msgsys->addUUIDFast(_PREHASH_SessionID, getSessionID());
msgsys->addBOOLFast(_PREHASH_AlwaysRun, BOOL(running) );
// msgsys->addBOOLFast(_PREHASH_AlwaysRun, BOOL(running) );
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
msgsys->addBOOLFast(_PREHASH_AlwaysRun, BOOL(getRunning()) );
// [/RLVa:KB]
sendReliableMessage();
}
}
@ -3485,7 +3521,7 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
: gRlvHandler.hasBehaviour(RLV_BHVR_TPLM) && gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC) ) ||
((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (isAgentAvatarValid()) && (gAgentAvatarp->isSitting())) ))
{
RlvUtil::notifyBlockedTeleport();
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT);
return;
}
// [/RLVa:KB]
@ -3562,7 +3598,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
( (isAgentAvatarValid()) && (gAgentAvatarp->isSitting()) &&
(gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) )
{
RlvUtil::notifyBlockedTeleport();
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT);
return;
}
@ -3620,7 +3656,7 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
if ( (rlv_handler_t::isEnabled()) && (!RlvUtil::isForceTp()) &&
((gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) || (!gRlvHandler.canStand())) )
{
RlvUtil::notifyBlockedTeleport();
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT);
return;
}
// [/RLVa:KB]

View File

@ -330,19 +330,31 @@ public:
DOUBLETAP_SLIDERIGHT
};
void setAlwaysRun() { mbAlwaysRun = true; }
void clearAlwaysRun() { mbAlwaysRun = false; }
void setRunning() { mbRunning = true; }
void clearRunning() { mbRunning = false; }
void sendWalkRun(bool running);
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
void setAlwaysRun();
void setTempRun();
void clearAlwaysRun();
void clearTempRun();
void sendWalkRun();
bool getTempRun() { return mbTempRun; }
bool getRunning() const { return (mbAlwaysRun) || (mbTempRun); }
// [/RLVa:KB]
// void setAlwaysRun() { mbAlwaysRun = true; }
// void clearAlwaysRun() { mbAlwaysRun = false; }
// void setRunning() { mbRunning = true; }
// void clearRunning() { mbRunning = false; }
// void sendWalkRun(bool running);
bool getAlwaysRun() const { return mbAlwaysRun; }
bool getRunning() const { return mbRunning; }
// bool getRunning() const { return mbRunning; }
public:
LLFrameTimer mDoubleTapRunTimer;
EDoubleTapRunMode mDoubleTapRunMode;
private:
bool mbAlwaysRun; // Should the avatar run by default rather than walk?
bool mbRunning; // Is the avatar trying to run right now?
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
bool mbTempRun;
// [/RLVa:KB]
// bool mbRunning; // Is the avatar trying to run right now?
bool mbTeleportKeepsLookAt; // Try to keep look-at after teleport is complete
//--------------------------------------------------------------------

View File

@ -37,8 +37,9 @@
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
// [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "llvoavatarself.h"
// [/RLVa:KB]
LLAgentListener::LLAgentListener(LLAgent &agent)

View File

@ -49,8 +49,9 @@
#include "llvoavatarself.h"
#include "llwearable.h"
#include "llwearablelist.h"
// [RLVa:KB] - Checked: RLVa-1.2.0a (2010-03-04)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#include <boost/scoped_ptr.hpp>
@ -945,6 +946,30 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32
return LLUUID();
}
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void LLAgentWearables::getWearableItemIDs(uuid_vec_t& idItems) const
{
for (wearableentry_map_t::const_iterator itWearableType = mWearableDatas.begin();
itWearableType != mWearableDatas.end(); ++itWearableType)
{
getWearableItemIDs(itWearableType->first, idItems);
}
}
void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_t& idItems) const
{
wearableentry_map_t::const_iterator itWearableType = mWearableDatas.find(eType);
if (mWearableDatas.end() != itWearableType)
{
for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(), endWearable = itWearableType->second.end();
itWearable != endWearable; ++itWearable)
{
idItems.push_back((*itWearable)->getItemID());
}
}
}
// [/RLVa:KB]
const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
{
const LLWearable *wearable = getWearable(type,index);
@ -1983,9 +2008,11 @@ void LLAgentWearables::userRemoveAllAttachments()
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
// [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
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
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
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
for (S32 idxItem = obj_item_array.count() - 1; idxItem >= 0; idxItem--)
@ -2037,8 +2064,8 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD); // Wear at the previous or default attachment point
// [RLVa:KB] - Checked: 2010-07-28 (RLVa-1.2.0i) | Added: RLVa-1.2.0i
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) )
{
RlvAttachmentLockWatchdog::instance().onWearAttachment(item, RLV_WEAR_ADD);
}
@ -2053,6 +2080,10 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->sendReliable( gAgent.getRegion()->getHost() );
}
}
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
sInitialAttachmentsRequested = true;
// [/RLVa:KB]
}
void LLAgentWearables::checkWearablesLoaded() const

View File

@ -93,6 +93,10 @@ public:
// Accessors
//--------------------------------------------------------------------
public:
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void getWearableItemIDs(uuid_vec_t& idItems) const;
void getWearableItemIDs(LLWearableType::EType eType, uuid_vec_t& idItems) const;
// [/RLVa:KB]
const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
const LLWearable* getWearableFromItemID(const LLUUID& item_id) const;

View File

@ -49,8 +49,10 @@
#include "llvoavatarself.h"
#include "llviewerregion.h"
#include "llwearablelist.h"
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0b)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvhelper.h"
#include "rlvlocks.h"
// [/RLVa:KB]
// RAII thingy to guarantee that a variable gets reset when the Setter
@ -1738,6 +1740,14 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
lldebugs << "updateAgentWearables()" << llendl;
LLInventoryItem::item_array_t items;
LLDynamicArray< LLWearable* > wearables;
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
uuid_vec_t idsCurrent; LLInventoryModel::item_array_t itemsNew;
if (rlv_handler_t::isEnabled())
{
// Collect the item UUIDs of all currently worn wearables
gAgentWearables.getWearableItemIDs(idsCurrent);
}
// [/RLVa:KB]
// For each wearable type, find the wearables of that type.
for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
@ -1773,11 +1783,39 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
// [/RLVa:KB]
items.put(item);
wearables.put(wearable);
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
if ( (rlv_handler_t::isEnabled()) && (gAgentWearables.areInitalWearablesLoaded()) )
{
// Remove the wearable from current item UUIDs if currently worn and requested, otherwise mark it as a new item
uuid_vec_t::iterator itItemID = std::find(idsCurrent.begin(), idsCurrent.end(), item->getUUID());
if (idsCurrent.end() != itItemID)
idsCurrent.erase(itItemID);
else
itemsNew.push_back(item);
}
// [/RLVa:KB]
}
}
}
}
// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
if ( (rlv_handler_t::isEnabled()) && (gAgentWearables.areInitalWearablesLoaded()) )
{
// 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 LLWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID);
if (pWearable)
RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true);
}
for (S32 idxItem = 0, cntItem = itemsNew.count(); idxItem < cntItem; idxItem++)
{
RlvBehaviourNotifyHandler::onWear(itemsNew.get(idxItem)->getWearableType(), true);
}
}
// [/RLVa:KB]
if(wearables.count() > 0)
{
gAgentWearables.setWearableOutfit(items, wearables, !append);
@ -2129,7 +2167,7 @@ void LLAppearanceMgr::getUserDescendents(const LLUUID& category,
}
void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)
//-TT Patch: ReplaceWornItemsOnly
//-TT Patch: ReplaceWornItemsOnly
{
wearInventoryCategory(category, copy, append, false);
}
@ -2146,26 +2184,26 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
&LLAppearanceMgr::instance(),
category->getUUID(), copy, append));
//-TT Patch: ReplaceWornItemsOnly
//-TT Patch: ReplaceWornItemsOnly
//category->getUUID(), copy, append, replace));
//-TT
}
//-TT Patch: ReplaceWornItemsOnly
//-TT Patch: ReplaceWornItemsOnly
void LLAppearanceMgr::replaceCategoryInCurrentOutfit(const LLUUID& cat_id)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
wearInventoryCategory(cat, false, true);
}
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
wearInventoryCategory(cat, false, true);
}
//-TT
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
//-TT Patch: ReplaceWornItemsOnly
//-TT Patch: ReplaceWornItemsOnly
{
wearCategoryFinal(cat_id, copy_items, append, false);
}
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append, bool replace)
//-TT
//-TT
{
llinfos << "starting" << llendl;

View File

@ -33,8 +33,9 @@
#include "llviewerinventory.h"
#include "llviewerregion.h"
#include "message.h"
// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
LLAttachmentsMgr::LLAttachmentsMgr()

View File

@ -73,6 +73,9 @@
#include "llviewercontrol.h"
#include "llfloaterreporter.h"
#include "llviewermenu.h"
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
#include "rlvhandler.h"
// [/RLVa:KB]
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
@ -196,6 +199,19 @@ void LLAvatarActions::startIM(const LLUUID& id)
if (id.isNull())
return;
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(id)) )
{
LLUUID idSession = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
return;
}
}
// [/RLVa:KB]
LLAvatarNameCache::get(id,
boost::bind(&on_avatar_name_cache_start_im, _1, _2));
}
@ -232,6 +248,20 @@ void LLAvatarActions::startCall(const LLUUID& id)
{
return;
}
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(id)) )
{
LLUUID idSession = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
if ( (idSession.notNull()) && (!gIMMgr->hasSession(idSession)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
return;
}
}
// [/RLVa:KB]
LLAvatarNameCache::get(id,
boost::bind(&on_avatar_name_cache_start_call, _1, _2));
}
@ -248,7 +278,17 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
LLDynamicArray<LLUUID> id_array;
for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
id_array.push_back(*it);
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
const LLUUID& idAgent = *it;
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString()));
return;
}
id_array.push_back(idAgent);
// [/RLVa:KB]
// id_array.push_back(*it);
}
// create the new ad hoc voice session
@ -293,7 +333,17 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
LLDynamicArray<LLUUID> id_array;
for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
id_array.push_back(*it);
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
const LLUUID& idAgent = *it;
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(idAgent)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTCONF, LLSD().with("RECIPIENT", LLSLURL("agent", idAgent, "completename").getSLURLString()));
return;
}
id_array.push_back(idAgent);
// [/RLVa:KB]
// id_array.push_back(*it);
}
const std::string title = LLTrans::getString("conference-title");
LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);

View File

@ -529,7 +529,10 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask,
std::string avatar_name = selection->getColumn(0)->getValue().asString();
if (dest_agent_id.notNull() && dest_agent_id != gAgentID)
{
if (drop)
// if (drop)
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
if ( (drop) && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.canStartIM(dest_agent_id)) ) )
// [/RLVa:KB]
{
// Start up IM before give the item
session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id);

View File

@ -40,8 +40,9 @@
#include "llviewercontrol.h"
#include "llviewerobject.h"
#include "lluictrlfactory.h"
// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.2a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "llagent.h"
// [/RLVa:KB]
//LLFloaterInspect* LLFloaterInspect::sInstance = NULL;

View File

@ -42,6 +42,9 @@
#include "llimfloater.h"
//-TT - Patch : ShowGroupFloaters
#include "llpanelgroup.h"
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
#include "rlvhandler.h"
// [/RLVa:KB]
//
// Globals
@ -128,6 +131,15 @@ void LLGroupActions::startCall(const LLUUID& group_id)
return;
}
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(group_id)) && (!gIMMgr->hasSession(group_id)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString()));
return;
}
// [/RLVa:KB]
LLUUID session_id = gIMMgr->addSession(gdata.mName, IM_SESSION_GROUP_START, group_id, true);
if (session_id == LLUUID::null)
{
@ -201,8 +213,12 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response)
// static
void LLGroupActions::leave(const LLUUID& group_id)
{
if (group_id.isNull())
// if (group_id.isNull())
// return;
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) )
return;
// [/RLVa:KB]
S32 count = gAgent.mGroups.count();
S32 i;
@ -224,6 +240,11 @@ void LLGroupActions::leave(const LLUUID& group_id)
// static
void LLGroupActions::activate(const LLUUID& group_id)
{
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
if (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))
return;
// [/RLVa:KB]
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ActivateGroup);
msg->nextBlockFast(_PREHASH_AgentData);
@ -371,6 +392,15 @@ void LLGroupActions::startIM(const LLUUID& group_id)
if (group_id.isNull())
return;
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStartIM(group_id)) && (!gIMMgr->hasSession(group_id)) )
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString()));
return;
}
// [/RLVa:KB]
LLGroupData group_data;
if (gAgent.getGroupData(group_id, group_data))
{

View File

@ -43,6 +43,9 @@
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#include "llvoiceclient.h"
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
#include "rlvhandler.h"
// [/RLVa:KB]
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
S32 LLGroupListItem::sIconWidth = 0;
@ -296,8 +299,14 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected
// each group including "none" can be activated
// if (userdata.asString() == "activate")
// return gAgent.getGroupID() != selected_group_id;
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
if (userdata.asString() == "activate")
return gAgent.getGroupID() != selected_group_id;
return (gAgent.getGroupID() != selected_group_id) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP));
else if (userdata.asString() == "leave")
return (gAgent.getGroupID() != selected_group_id) || (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP));
// [/RLVa:KB]
if (userdata.asString() == "call")
return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();

File diff suppressed because it is too large Load Diff

View File

@ -81,8 +81,9 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
BOOL LLInventoryState::sWearNewClothing = FALSE;
@ -354,6 +355,14 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
}
}
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( (rlv_handler_t::isEnabled()) &&
(RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(id)) )
{
return FALSE;
}
// [/RLVa:KB]
const LLInventoryObject *obj = model->getItem(id);
if (obj && obj->getIsLinkType())
{
@ -382,8 +391,9 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
return FALSE;
}
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
if ( (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().isLockedFolder(id, RLV_LOCK_ANY)) )
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( ((rlv_handler_t::isEnabled()) &&
(RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveFolder(id))) )
{
return FALSE;
}
@ -430,9 +440,8 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
return FALSE;
}
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
if ( (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().isLockedFolder(id, RLV_LOCK_ANY)) &&
(model->isObjectDescendentOf(id, gInventory.getRootFolderID())) )
// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
if ( (rlv_handler_t::isEnabled()) && (model == &gInventory) && (!RlvFolderLocks::instance().canRenameFolder(id)) )
{
return FALSE;
}

View File

@ -46,8 +46,9 @@
#include "llviewerregion.h"
#include "llcallbacklist.h"
#include "llvoavatarself.h"
// [RLVa:KB] - Checked: RLVa-1.2.0a (2010-03-05)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
//-TT Patch: ReplaceWornItemsOnly
#include "llviewerobjectlist.h"

View File

@ -877,8 +877,11 @@ bool LLInventoryPanel::beginIMSession()
std::string name;
static int session_num = 1;
LLDynamicArray<LLUUID> members;
EInstantMessage type = IM_SESSION_CONFERENCE_START;
// LLDynamicArray<LLUUID> members;
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
uuid_vec_t members;
// [/RLVa:KB]
// EInstantMessage type = IM_SESSION_CONFERENCE_START;
std::set<LLUUID>::const_iterator iter;
for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
@ -920,7 +923,10 @@ bool LLInventoryPanel::beginIMSession()
id = item_array.get(i)->getCreatorUUID();
if(at.isBuddyOnline(id))
{
members.put(id);
// members.put(id);
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
members.push_back(id);
// [/RLVa:KB]
}
}
}
@ -942,7 +948,10 @@ bool LLInventoryPanel::beginIMSession()
if(at.isBuddyOnline(id))
{
members.put(id);
// members.put(id);
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
members.push_back(id);
// [/RLVa:KB]
}
}
} //if IT_CALLINGCARD
@ -958,11 +967,14 @@ bool LLInventoryPanel::beginIMSession()
name = llformat("Session %d", session_num++);
}
LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
if (session_id != LLUUID::null)
{
LLIMFloater::show(session_id);
}
// LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
// if (session_id != LLUUID::null)
// {
// LLIMFloater::show(session_id);
// }
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
LLAvatarActions::startConference(members);
// [/RLVa:KB]
return true;
}

View File

@ -325,23 +325,32 @@ void LLFloaterMove::setMovementMode(const EMovementMode mode)
{
case MM_RUN:
gAgent.setAlwaysRun();
gAgent.setRunning();
// gAgent.setRunning();
break;
case MM_WALK:
gAgent.clearAlwaysRun();
gAgent.clearRunning();
// gAgent.clearRunning();
break;
default:
//do nothing for other modes (MM_FLY)
break;
}
// tell the simulator.
gAgent.sendWalkRun(gAgent.getAlwaysRun());
updateButtonsWithMovementMode(mode);
// gAgent.sendWalkRun(gAgent.getAlwaysRun());
//
// updateButtonsWithMovementMode(mode);
//
// bool bHideModeButtons = MM_FLY == mode
// || (isAgentAvatarValid() && gAgentAvatarp->isSitting());
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
// Running may have been restricted so update walk-vs-run from the agent's actual running state
if ( (MM_WALK == mode) || (MM_RUN == mode) )
mCurrentMode = (gAgent.getRunning()) ? MM_RUN : MM_WALK;
bool bHideModeButtons = MM_FLY == mode
|| (isAgentAvatarValid() && gAgentAvatarp->isSitting());
updateButtonsWithMovementMode(mCurrentMode);
bool bHideModeButtons = (MM_FLY == mCurrentMode) || (isAgentAvatarValid() && gAgentAvatarp->isSitting());
// [/RLVa:KB]
showModeButtons(!bHideModeButtons);

View File

@ -415,6 +415,13 @@ private:
*/
static LLIMFloater* findIMFloater(const LLNotificationPtr& notification);
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
/**
* Checks whether the user has opted to embed (certain) notifications in IM sessions
*/
static bool canEmbedNotificationInIM(const LLNotificationPtr& notification);
// [/SL:KB]
};
}

View File

@ -37,6 +37,9 @@
#include "llfloaterreg.h"
#include "llnearbychat.h"
#include "llimfloater.h"
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
#include "rlvhandler.h"
// [/RLVa:KB]
using namespace LLNotificationsUI;
@ -166,25 +169,67 @@ bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
// static
bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName();
// return OFFER_FRIENDSHIP == notification->getName()
// || USER_GIVE_ITEM == notification->getName()
// || TELEPORT_OFFERED == notification->getName();
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
// return
// (canEmbedNotificationInIM(notification)) &&
// ( (OFFER_FRIENDSHIP == notification->getName()) || (USER_GIVE_ITEM == notification->getName()) ||
// (TELEPORT_OFFERED == notification->getName()) );
// [/SL:KB]
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
return
(canEmbedNotificationInIM(notification)) &&
( (!rlv_handler_t::isEnabled()) || (gRlvHandler.canStartIM(notification->getPayload()["from_id"].asUUID())) ) &&
( (OFFER_FRIENDSHIP == notification->getName()) || (USER_GIVE_ITEM == notification->getName()) ||
(TELEPORT_OFFERED == notification->getName()) );
// [/RLVa:KB]
}
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
// static
bool LLHandlerUtil::canEmbedNotificationInIM(const LLNotificationPtr& notification)
{
switch (gSavedSettings.getS32("NotificationCanEmbedInIM"))
{
case 1: // Focused
return isIMFloaterFocused(notification);
case 2: // Never
return false;
case 0: // Always (Viewer 2 default)
default:
return true;
}
}
// [/SL:KB]
// static
bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName();
// return OFFER_FRIENDSHIP == notification->getName()
// || USER_GIVE_ITEM == notification->getName()
// || TELEPORT_OFFERED == notification->getName();
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
return
(canEmbedNotificationInIM(notification)) &&
( (OFFER_FRIENDSHIP == notification->getName()) || (USER_GIVE_ITEM == notification->getName()) ||
(TELEPORT_OFFERED == notification->getName()) );
// [/SL:KB]
}
// static
bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName();
// return OFFER_FRIENDSHIP == notification->getName()
// || USER_GIVE_ITEM == notification->getName()
// || TELEPORT_OFFERED == notification->getName();
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
return
(canEmbedNotificationInIM(notification)) &&
( (OFFER_FRIENDSHIP == notification->getName()) || (USER_GIVE_ITEM == notification->getName()) ||
(TELEPORT_OFFERED == notification->getName()) );
// [/SL:KB]
}
// static
@ -214,7 +259,11 @@ bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
|| TELEPORT_OFFERED == notification->getName())
{
// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
return ! isIMFloaterOpened(notification);
// return ! isIMFloaterOpened(notification);
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
// Force a toast if the user opted not to embed notifications panels in IMs
return (!canEmbedNotificationInIM(notification)) || (!isIMFloaterOpened(notification));
// [/SL:KB]
}
return true;

View File

@ -101,12 +101,14 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
LLUUID session_id;
// if (LLHandlerUtil::canSpawnIMSession(notification))
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
// [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h
// Don't spawn a new IM session for inventory offers if this notification was subject to @shownames=n
// RELEASE-RLVa: [SL-2.3.0] Test on every new release to make sure the notification gets routed the way we want it to be
bool fSpawnIM = (LLHandlerUtil::canSpawnIMSession(notification)) && (!notification->getPayload().has("rlv_shownames"));
if (fSpawnIM)
bool spawn_session = (LLHandlerUtil::canSpawnIMSession(notification)) && (!notification->getPayload().has("rlv_shownames"));
// [/RLVa:KB]
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
// bool spawn_session = LLHandlerUtil::canSpawnIMSession(notification);
if (spawn_session)
// [/SL:KB]
{
const std::string name = LLHandlerUtil::getSubstitutionName(notification);
@ -117,11 +119,11 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
bool show_toast = LLHandlerUtil::canSpawnToast(notification);
// bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
// NOTE: add_notid_to_im needs to be FALSE if we suppressed spawning an IM because in that case the notification needs to
// be routed to the "syswell" or the inventory offer floater will dissapear and the user won't be able to accept it
bool add_notid_to_im = (fSpawnIM) && (LLHandlerUtil::canAddNotifPanelToIM(notification));
// [/RLVa:KB]
bool add_notid_to_im = (spawn_session) && (LLHandlerUtil::canAddNotifPanelToIM(notification));
// [/SL:KB]
if (add_notid_to_im)
{
LLHandlerUtil::addNotifPanelToIM(notification);
@ -191,19 +193,11 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
{
// if (LLHandlerUtil::canAddNotifPanelToIM(notification)
// && !LLHandlerUtil::isIMFloaterOpened(notification))
// [SL:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
// Repro:
// 1) have someone drop you 2 inventory items (new IM session will be spawned)
// 2) accept/decline the inventory offers as they come in
// -> unread IM counter shows 0
// 3) toggle "Enable plain text chat history" while the IM session with the inventory offers isn't the active session
// -> unread IM counter shows -2
// -> LLHandlerUtil::decIMMesageCounter() really should be fixed to check for "0" before decreasing the count but
// there are enough bugfixes in RLVa as it is already :(
// Fix:
// - the one and only time we need to decrease the unread IM count is when we've clicked any of the buttons on the *toast*
// - since LLIMFloater::updateMessages() hides the toast when we open the IM (which resets the unread count to 0) we should
// *only* decrease the unread IM count if there's a visible toast since the unread count will be at 0 otherwise anyway
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
// LLHandlerUtil::canAddNotifPanelToIM() won't necessarily tell us whether the notification went into an IM or to the syswell
// -> the one and only time we need to decrease the unread IM count is when we've clicked any of the buttons on the *toast*
// -> since LLIMFloater::updateMessages() hides the toast when we open the IM (which resets the unread count to 0) we should
// *only* decrease the unread IM count if there's a visible toast since the unread count will be at 0 otherwise anyway
LLScreenChannel* pChannel = dynamic_cast<LLScreenChannel*>(mChannel);
LLToast* pToast = (pChannel) ? pChannel->getToastByNotificationID(notification->getID()) : NULL;
if ( (pToast) && (!pToast->getCanBeStored()) )
@ -223,10 +217,9 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
void LLOfferHandler::onDeleteToast(LLToast* toast)
{
// if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification()))
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
// BUGFIX: LLHandlerUtil::canAddNotifPanelToIM() won't necessarily tell us whether the notification went into an IM or to the syswell
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
if (toast->getCanBeStored())
// [/RLVa:KB]
// [/SL:KB]
{
// send a signal to the counter manager
mDelNotificationSignal();
@ -242,12 +235,25 @@ void LLOfferHandler::onRejectToast(LLUUID& id)
{
LLNotificationPtr notification = LLNotifications::instance().find(id);
if (notification
&& LLNotificationManager::getInstance()->getHandlerForNotification(
notification->getType()) == this
// don't delete notification since it may be used by IM floater
&& !LLHandlerUtil::canAddNotifPanelToIM(notification))
// if (notification
// && LLNotificationManager::getInstance()->getHandlerForNotification(
// notification->getType()) == this
// // don't delete notification since it may be used by IM floater
// && !LLHandlerUtil::canAddNotifPanelToIM(notification))
// {
// LLNotifications::instance().cancel(notification);
// }
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
// NOTE: this will be fired from LLScreenChannel::killToastByNotificationID() which treats visible and stored toasts differently
if ( (notification) && (!notification->isCancelled()) &&
(LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this) )
{
LLNotifications::instance().cancel(notification);
LLScreenChannel* pChannel = dynamic_cast<LLScreenChannel*>(mChannel);
LLToast* pToast = (pChannel) ? pChannel->getToastByNotificationID(notification->getID()) : NULL;
if ( (!pToast) || (pToast->getCanBeStored()) )
{
LLNotifications::instance().cancel(notification);
}
}
// [/SL:KB]
}

View File

@ -59,8 +59,9 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llworld.h"
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
//

View File

@ -41,10 +41,6 @@
#include "llsidetray.h"
#include "llviewercontrol.h"
#include "llviewerdisplayname.h"
// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a)
#include "rlvhandler.h"
#include "rlvui.h"
// [/RLVa:KB]
// Linden libraries
#include "llavatarnamecache.h" // IDEVO
@ -199,9 +195,6 @@ LLPanelMyProfileEdit::LLPanelMyProfileEdit()
setAvatarId(gAgent.getID());
LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLPanelMyProfileEdit::onAvatarNameChanged, this));
// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.1a
RlvUIEnabler::instance().addBehaviourToggleCallback(RLV_BHVR_DISPLAYNAME, boost::bind(&LLPanelMyProfileEdit::onAvatarNameChanged, this));
// [/RLVa:KB]
}
void LLPanelMyProfileEdit::onOpen(const LLSD& key)
@ -235,10 +228,7 @@ void LLPanelMyProfileEdit::onOpen(const LLSD& key)
getChild<LLUICtrl>("user_slid")->setVisible( true );
getChild<LLUICtrl>("display_name_label")->setVisible( true );
getChild<LLUICtrl>("set_name")->setVisible( true );
// getChild<LLUICtrl>("set_name")->setEnabled( true );
// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.1a
getChild<LLUICtrl>("set_name")->setEnabled( !gRlvHandler.hasBehaviour(RLV_BHVR_DISPLAYNAME) );
// [/RLVa:KB]
getChild<LLUICtrl>("set_name")->setEnabled( true );
getChild<LLUICtrl>("solo_user_name")->setVisible( false );
getChild<LLUICtrl>("solo_username_label")->setVisible( false );
}
@ -310,10 +300,7 @@ void LLPanelMyProfileEdit::onNameCache(const LLUUID& agent_id, const LLAvatarNam
getChild<LLUICtrl>("user_slid")->setVisible( true );
getChild<LLUICtrl>("display_name_label")->setVisible( true );
getChild<LLUICtrl>("set_name")->setVisible( true );
// getChild<LLUICtrl>("set_name")->setEnabled( true );
// [RLVa:KB] - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.1a
getChild<LLUICtrl>("set_name")->setEnabled( !gRlvHandler.hasBehaviour(RLV_BHVR_DISPLAYNAME) );
// [/RLVa:KB]
getChild<LLUICtrl>("set_name")->setEnabled( true );
getChild<LLUICtrl>("solo_user_name")->setVisible( false );
getChild<LLUICtrl>("solo_username_label")->setVisible( false );

View File

@ -68,8 +68,9 @@
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
//#include "llfirstuse.h"
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "llvoavatarself.h"
// [/RLVa:KB]
#include "lldrawpool.h"

View File

@ -63,8 +63,9 @@
#include "llviewerregion.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h"
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.2.0b)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
///----------------------------------------------------------------------------

View File

@ -1052,7 +1052,11 @@ void LLPanelPeople::updateButtons()
}
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
// groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
groups_panel->getChildView("activate_btn")->setEnabled(
item_selected && !cur_group_active && !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)); // "none" or a non-active group selected
// [/RLVa:KB]
groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull());
}
else

View File

@ -85,8 +85,9 @@
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llappviewer.h"
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
const std::string HELLO_LSL =

View File

@ -860,8 +860,7 @@ LLToast* LLScreenChannel::getToastByNotificationID(LLUUID id)
// if (it == mStoredToastList.end())
// return NULL;
// [SL:KB] - Checked: 2010-04-21 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
// BUGFIX-SL: we need to get the visible toast in LLOfferHandler::processNotification() whether it's "stored" or not
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Modified: Catznip-2.5.0a
if (it == mStoredToastList.end())
{
// If we can't find it among the stored toasts then widen it to "all visible toasts"

View File

@ -90,7 +90,7 @@
#include "llvoavatarself.h"
#include "llvovolume.h"
#include "pipeline.h"
// [RLVa:KB] - Checked: 2010-03-23 (RLVa-1.2.0a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
// [/RLVa:KB]

View File

@ -47,7 +47,10 @@ LLToastPanel::~LLToastPanel()
std::string LLToastPanel::getTitle()
{
// *TODO: create Title and localize it. If it will be required.
return mNotification->getMessage();
// return mNotification->getMessage();
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
return (mNotification->hasLabel()) ? mNotification->getLabel() : mNotification->getMessage();
// [/SL:KB]
}
//virtual

View File

@ -60,8 +60,9 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llworld.h"
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
// syntactic sugar

View File

@ -77,8 +77,9 @@
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llpostprocess.h"
// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
extern LLPointer<LLViewerTexture> gStartTexture;

View File

@ -329,8 +329,11 @@ void LLViewerJoystick::handleRun(F32 inc)
if (1 == mJoystickRun)
{
++mJoystickRun;
gAgent.setRunning();
gAgent.sendWalkRun(gAgent.getRunning());
// gAgent.setRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
gAgent.setTempRun();
// [/RLVa:KB]
}
else if (0 == mJoystickRun)
{
@ -345,8 +348,11 @@ void LLViewerJoystick::handleRun(F32 inc)
--mJoystickRun;
if (0 == mJoystickRun)
{
gAgent.clearRunning();
gAgent.sendWalkRun(gAgent.getRunning());
// gAgent.clearRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
gAgent.clearTempRun();
// [/RLVa:KB]
}
}
}

View File

@ -41,6 +41,9 @@
#include "llvoavatarself.h"
#include "llfloatercamera.h"
#include "llinitparam.h"
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
#include "rlvhandler.h"
// [/RLVa:KB]
//
// Constants
@ -91,14 +94,18 @@ static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode m
{
if (KEYSTATE_UP == s)
{
if (gAgent.mDoubleTapRunMode == mode &&
gAgent.getRunning() &&
!gAgent.getAlwaysRun())
{
// Turn off temporary running.
gAgent.clearRunning();
gAgent.sendWalkRun(gAgent.getRunning());
}
// if (gAgent.mDoubleTapRunMode == mode &&
// gAgent.getRunning() &&
// !gAgent.getAlwaysRun())
// {
// // Turn off temporary running.
// gAgent.clearRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// }
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) )
gAgent.clearTempRun();
// [/RLVa:KB]
}
else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
KEYSTATE_DOWN == s &&
@ -109,8 +116,11 @@ static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode m
{
// Same walk-key was pushed again quickly; this is a
// double-tap so engage temporary running.
gAgent.setRunning();
gAgent.sendWalkRun(gAgent.getRunning());
// gAgent.setRunning();
// gAgent.sendWalkRun(gAgent.getRunning());
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
gAgent.setTempRun();
// [/RLVa:KB]
}
// Pressing any walk-key resets the double-tap timer

View File

@ -105,9 +105,9 @@
#include "lltrans.h"
#include "lleconomy.h"
#include "boost/unordered_map.hpp"
// [RLVa:KB] - Checked: 2010-03-09 (RLVa-1.2.0a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
using namespace LLVOAvatarDefines;
@ -5496,16 +5496,16 @@ class LLWorldAlwaysRun : public view_listener_t
if (gAgent.getAlwaysRun())
{
gAgent.clearAlwaysRun();
gAgent.clearRunning();
// gAgent.clearRunning();
}
else
{
gAgent.setAlwaysRun();
gAgent.setRunning();
// gAgent.setRunning();
}
// tell the simulator.
gAgent.sendWalkRun(gAgent.getAlwaysRun());
// gAgent.sendWalkRun(gAgent.getAlwaysRun());
// Update Movement Controls according to AlwaysRun mode
LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun());

View File

@ -1485,7 +1485,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// end has already copied the items into your inventory,
// so we can fetch it out of our inventory.
// [RLVa:KB] - Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
#ifdef RLV_EXTENSION_GIVETORLV_A2A
if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getForbidGiveToRLV()) && (LLAssetType::AT_CATEGORY == mType) &&
(RlvInventory::instance().getSharedRoot()) && (mDesc.find(RLV_PUTINV_PREFIX) == 0) )
{
@ -1496,7 +1495,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
else
gInventory.addObserver(pOfferObserver);
}
#endif // RLV_EXTENSION_GIVETORLV_A2A
// [/RLVa:KB]
LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string);
@ -1752,7 +1750,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
{
std::string::size_type idxToken = mDesc.find("' ( http://");
if (std::string::npos != idxToken)
RlvBehaviourNotifyHandler::instance().sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1));
RlvBehaviourNotifyHandler::sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1));
}
// [/RLVa:KB]
@ -1810,7 +1808,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
{
std::string::size_type idxToken = mDesc.find("' ( http://");
if (std::string::npos != idxToken)
RlvBehaviourNotifyHandler::instance().sendNotification("declined inv_offer " + mDesc.substr(1, idxToken - 1));
RlvBehaviourNotifyHandler::sendNotification("declined inv_offer " + mDesc.substr(1, idxToken - 1));
}
// [/RLVa:KB]
@ -1951,6 +1949,9 @@ void inventory_offer_handler(LLOfferInfo* info)
}
else
{
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
args["NAME_LABEL"] = LLSLURL("agent", info->mFromID, "completename").getSLURLString();
// [/SL:KB]
args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString();
}
std::string verb = "select?name=" + LLURI::escape(msg);
@ -3052,6 +3053,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLSD args;
// *TODO: Translate -> [FIRST] [LAST] (maybe)
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
// [/SL:KB]
args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
args["MESSAGE"] = message;
args["MATURITY_STR"] = region_access_str;
@ -3138,6 +3142,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
else
{
// [SL:KB] - Patch: UI-Notifications | Checked: 2011-04-11 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
args["NAME_LABEL"] = LLSLURL("agent", from_id, "completename").getSLURLString();
// [/SL:KB]
args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
if(message.empty())
{
@ -4258,7 +4265,10 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
}
// send walk-vs-run status
gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
// gAgent.sendWalkRun(gAgent.getRunning() || gAgent.getAlwaysRun());
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
gAgent.sendWalkRun();
// [/RLVa:KB]
// If the server version has changed, display an info box and offer
// to display the release notes, unless this is the initial log in.

View File

@ -100,8 +100,9 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.2.0b)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
//#define DEBUG_UPDATE_TYPE

View File

@ -56,8 +56,9 @@
#include "llviewerstats.h"
#include "llviewerregion.h"
#include "llappearancemgr.h"
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#if LL_MSVC

View File

@ -63,8 +63,9 @@
#include "llmediadataclient.h"
#include "llagent.h"
#include "llviewermediafocus.h"
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
const S32 MIN_QUIET_FRAMES_COALESCE = 30;

View File

@ -40,8 +40,9 @@
#include "llviewermenu.h"
// [/SL:KB]
#include "llvoavatarself.h"
// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1a)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
class LLFindOutfitItems : public LLInventoryCollectFunctor

View File

@ -103,9 +103,9 @@
#if !LL_DARWIN
#include "llfloaterhardwaresettings.h"
#endif
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0d)
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#ifdef _DEBUG

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -17,7 +17,6 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llagentui.h"
#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llinstantmessage.h"
#include "llnotificationsutil.h"
@ -29,29 +28,16 @@
#include "llworld.h"
#include "rlvcommon.h"
#include "rlvhelper.h"
#include "rlvhandler.h"
#include "rlvlocks.h"
#include <boost/algorithm/string.hpp>
// ============================================================================
// RlvNotifications
//
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
/*
void RlvNotifications::notifyBehaviour(ERlvBehaviour eBhvr, ERlvParamType eType)
{
const std::string& strMsg = RlvStrings::getBehaviourNotificationString(eBhvr, eType);
if (!strMsg.empty())
{
LLSD argsNotify;
argsNotify["MESSAGE"] = strMsg;
LLNotifications::instance().add("SystemMessageTip", argsNotify);
}
}
*/
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
// Checked: 2009-11-13 (RLVa-1.1.0b) | Modified: RLVa-1.1.0b
/*
void RlvNotifications::warnGiveToRLV()
@ -150,10 +136,6 @@ bool RlvSettings::onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting)
std::vector<std::string> RlvStrings::m_Anonyms;
std::map<std::string, std::string> RlvStrings::m_StringMap;
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
std::map<ERlvBehaviour, std::string> RlvStrings::m_BhvrAddMap;
std::map<ERlvBehaviour, std::string> RlvStrings::m_BhvrRemMap;
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
// Checked: 2010-03-09 (RLVa-1.2.0a) | Added: RLVa-1.1.0h
void RlvStrings::initClass()
@ -189,25 +171,6 @@ void RlvStrings::initClass()
m_Anonyms.push_back(pAnonymNode->getTextContents());
}
}
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
else if (pNode->hasName("behaviour-notifications"))
{
std::string strBhvr, strType; ERlvBehaviour eBhvr;
for (LLXMLNode* pNotifyNode = pNode->getFirstChild(); pNotifyNode != NULL; pNotifyNode = pNotifyNode->getNextSibling())
{
if ( (!pNotifyNode->hasName("notification")) || (!pNotifyNode->getAttributeString("type", strType)) ||
(!pNotifyNode->getAttributeString("behaviour", strBhvr)) ||
((eBhvr = RlvCommand::getBehaviourFromString(strBhvr)) == RLV_BHVR_UNKNOWN) )
{
continue;
}
if ("add" == strType)
m_BhvrAddMap.insert(std::pair<ERlvBehaviour, std::string>(eBhvr, pNotifyNode->getTextContents()));
else if ("rem" == strType)
m_BhvrRemMap.insert(std::pair<ERlvBehaviour, std::string>(eBhvr, pNotifyNode->getTextContents()));
}
}
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
}
if ( (m_StringMap.empty()) || (m_Anonyms.empty()) )
@ -232,24 +195,6 @@ const std::string& RlvStrings::getAnonym(const std::string& strName)
return m_Anonyms[nHash % m_Anonyms.size()];
}
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
const std::string& RlvStrings::getBehaviourNotificationString(ERlvBehaviour eBhvr, ERlvParamType eType)
{
if (RLV_TYPE_ADD == eType)
{
std::map<ERlvBehaviour, std::string>::const_iterator itString = m_BhvrAddMap.find(eBhvr);
return (itString != m_BhvrAddMap.end()) ? itString->second : LLStringUtil::null;
}
else if (RLV_TYPE_REMOVE == eType)
{
std::map<ERlvBehaviour, std::string>::const_iterator itString = m_BhvrRemMap.find(eBhvr);
return (itString != m_BhvrRemMap.end()) ? itString->second : LLStringUtil::null;
}
return LLStringUtil::null;
}
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
// Checked: 2009-11-11 (RLVa-1.1.0a) | Added: RLVa-1.1.0a
const std::string& RlvStrings::getString(const std::string& strStringName)
{
@ -336,27 +281,23 @@ bool RlvUtil::m_fForceTp = false;
// Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a
void RlvUtil::filterLocation(std::string& strUTF8Text)
{
// TODO-RLVa: if either the region or parcel name is a simple word such as "a" or "the" then confusion will ensue?
// -> not sure how you would go about preventing this though :|...
// Filter any mention of the surrounding region names
LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList();
const std::string& strHiddenRegion = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
for (LLWorld::region_list_t::const_iterator itRegion = regions.begin(); itRegion != regions.end(); ++itRegion)
rlvStringReplace(strUTF8Text, (*itRegion)->getName(), strHiddenRegion);
boost::ireplace_all(strUTF8Text, (*itRegion)->getName(), strHiddenRegion);
// Filter any mention of the parcel name
LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance();
if (pParcelMgr)
rlvStringReplace(strUTF8Text, pParcelMgr->getAgentParcelName(), RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL));
boost::ireplace_all(strUTF8Text, pParcelMgr->getAgentParcelName(), RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL));
}
// Checked: 2010-12-08 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c
void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy)
{
std::vector<LLUUID> idAgents;
uuid_vec_t idAgents;
LLWorld::getInstance()->getAvatars(&idAgents, NULL);
for (int idxAgent = 0, cntAgent = idAgents.size(); idxAgent < cntAgent; idxAgent++)
{
LLAvatarName avName;
@ -370,17 +311,17 @@ void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy)
strLegacyName = avName.getLegacyName();
// If the display name is a subset of the legacy name we need to filter that first, otherwise it's the other way around
if (std::string::npos != strLegacyName.find(avName.mDisplayName))
if (boost::icontains(strLegacyName, avName.mDisplayName))
{
if (!strLegacyName.empty())
rlvStringReplace(strUTF8Text, strLegacyName, strAnonym);
rlvStringReplace(strUTF8Text, avName.mDisplayName, strAnonym);
boost::ireplace_all(strUTF8Text, strLegacyName, strAnonym);
boost::ireplace_all(strUTF8Text, avName.mDisplayName, strAnonym);
}
else
{
rlvStringReplace(strUTF8Text, avName.mDisplayName, strAnonym);
boost::ireplace_all(strUTF8Text, avName.mDisplayName, strAnonym);
if (!strLegacyName.empty())
rlvStringReplace(strUTF8Text, strLegacyName, strAnonym);
boost::ireplace_all(strUTF8Text, strLegacyName, strAnonym);
}
}
}
@ -421,27 +362,15 @@ bool RlvUtil::isNearbyRegion(const std::string& strRegion)
return false;
}
// Checked: 2010-10-07 (RLVa-1.2.1f) | Added: RLVa-1.2.1f
void RlvUtil::notifyBlocked(const std::string& strRlvString)
// Checked: 2011-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h
void RlvUtil::notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs)
{
LLSD argsNotify;
argsNotify["MESSAGE"] = RlvStrings::getString(strRlvString);
LLNotificationsUtil::add("SystemMessageTip", argsNotify);
}
std::string strMsg = RlvStrings::getString(strNotifcation);
LLStringUtil::format(strMsg, sdArgs);
// Checked: 2010-03-01 (RLVa-1.2.0b) | Added: RLVa-1.2.0a
void RlvUtil::notifyBlockedViewXXX(LLAssetType::EType assetType)
{
if (!RlvStrings::hasString(RLV_STRING_BLOCKED_VIEWXXX))
return;
LLStringUtil::format_map_t argsMsg; std::string strMsg = RlvStrings::getString(RLV_STRING_BLOCKED_VIEWXXX);
argsMsg["[TYPE]"] = LLAssetType::lookup(assetType);
LLStringUtil::format(strMsg, argsMsg);
LLSD argsNotify;
argsNotify["MESSAGE"] = strMsg;
LLNotificationsUtil::add("SystemMessageTip", argsNotify);
LLSD sdNotify;
sdNotify["MESSAGE"] = strMsg;
LLNotificationsUtil::add("SystemMessageTip", sdNotify);
}
// Checked: 2010-11-11 (RLVa-1.2.1g) | Added: RLVa-1.2.1g
@ -537,6 +466,32 @@ bool rlvMenuEnableIfNot(const LLSD& sdParam)
// Selection functors
//
// Checked: 2010-04-11 (RLVa-1.2.0b) | Modified: RLVa-0.2.0g
bool rlvCanDeleteOrReturn()
{
bool fIsAllowed = true;
if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ))
{
// We'll allow if none of the prims are owned by the avie or group owned
LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsOwnedByOrGroupOwned f(gAgent.getID());
if ( (handleSel.notNull()) && ((0 == handleSel->getRootObjectCount()) || (NULL != handleSel->getFirstRootNode(&f, FALSE))) )
fIsAllowed = false;
}
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (isAgentAvatarValid()) )
{
// We'll allow if the avie isn't sitting on any of the selected objects
LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsSittingOn f(gAgentAvatarp->getRoot());
if ( (handleSel.notNull()) && (handleSel->getFirstRootNode(&f, TRUE)) )
fIsAllowed = false;
}
return fIsAllowed;
}
// Checked: 2010-04-20 (RLVa-1.2.0f) | Modified: RLVa-0.2.0f
bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode)
{
@ -624,6 +579,18 @@ bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem)
return !rlvPredCanRemoveItem(pItem);
}
// Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
RlvPredIsEqualOrLinkedItem::RlvPredIsEqualOrLinkedItem(const LLUUID& idItem)
{
m_pItem = gInventory.getItem(idItem);
}
// Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
bool RlvPredIsEqualOrLinkedItem::operator()(const LLViewerInventoryItem* pItem) const
{
return (m_pItem) && (pItem) && (m_pItem->getLinkedUUID() == pItem->getLinkedUUID());
}
// ============================================================================
// Various public helper functions
//

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -18,21 +18,45 @@
#define RLV_COMMON_H
#include "llavatarname.h"
#include "llinventorymodel.h"
#include "llselectmgr.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "rlvdefines.h"
#ifdef LL_WINDOWS
#pragma warning (push)
#pragma warning (disable : 4702) // warning C4702: unreachable code
#endif
#include <boost/variant.hpp>
#ifdef LL_WINDOWS
#pragma warning (pop)
#endif
// ============================================================================
// Forward declarations
//
class RlvCommand;
//
// General viewer source
//
class LLInventoryItem;
class LLViewerInventoryCategory;
class LLViewerInventoryItem;
class LLViewerJointAttachment;
class LLWearable;
typedef std::vector<LLViewerObject*> llvo_vec_t;
typedef std::vector<const LLViewerObject*> c_llvo_vec_t;
//
// RLVa-specific
//
class RlvCommand;
typedef std::list<RlvCommand> rlv_command_list_t;
class RlvObject;
struct RlvException;
typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
class RlvGCTimer;
class RlvWLSnapshot;
// ============================================================================
// RlvSettings
@ -44,7 +68,7 @@ template<typename T> inline T rlvGetSetting(const std::string& strSetting, const
return (gSavedSettings.controlExists(strSetting)) ? gSavedSettings.get<T>(strSetting) : defaultValue;
}
template<typename T> inline T rlvGetPerUserSettings(const std::string& strSetting, const T& defaultValue)
template<typename T> inline T rlvGetPerUserSetting(const std::string& strSetting, const T& defaultValue)
{
RLV_ASSERT_DBG(gSavedPerAccountSettings.controlExists(strSetting));
return (gSavedPerAccountSettings.controlExists(strSetting)) ? gSavedPerAccountSettings.get<T>(strSetting) : defaultValue;
@ -74,7 +98,7 @@ public:
static bool getShowNameTags() { return fShowNameTags; }
#ifdef RLV_EXTENSION_STARTLOCATION
static bool getLoginLastLocation() { return rlvGetPerUserSettings<bool>(RLV_SETTING_LOGINLASTLOCATION, true); }
static bool getLoginLastLocation() { return rlvGetPerUserSetting<bool>(RLV_SETTING_LOGINLASTLOCATION, true); }
static void updateLoginLastLocation();
#endif // RLV_EXTENSION_STARTLOCATION
@ -113,10 +137,6 @@ public:
protected:
static std::vector<std::string> m_Anonyms;
static std::map<std::string, std::string> m_StringMap;
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
static std::map<ERlvBehaviour, std::string> m_BhvrAddMap;
static std::map<ERlvBehaviour, std::string> m_BhvrRemMap;
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
};
// ============================================================================
@ -136,10 +156,9 @@ public:
static bool isForceTp() { return m_fForceTp; }
static void forceTp(const LLVector3d& posDest); // Ignores restrictions that might otherwise prevent tp'ing
static void notifyBlocked(const std::string& strRlvString);
static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD());
static void notifyBlockedGeneric() { notifyBlocked(RLV_STRING_BLOCKED_GENERIC); }
static void notifyBlockedTeleport() { notifyBlocked(RLV_STRING_BLOCKED_TELEPORT); }
static void notifyBlockedViewXXX(LLAssetType::EType assetType);
static void notifyBlockedViewXXX(LLAssetType::EType assetType) { notifyBlocked(RLV_STRING_BLOCKED_VIEWXXX, LLSD().with("[TYPE]", LLAssetType::lookup(assetType))); }
static void notifyFailedAssertion(const std::string& strAssert, const std::string& strFile, int nLine);
static void sendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null);
@ -178,6 +197,8 @@ bool rlvMenuEnableIfNot(const LLSD& sdParam);
// Selection functors
//
bool rlvCanDeleteOrReturn();
struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor
{
RlvSelectHasLockedAttach() {}
@ -235,16 +256,18 @@ protected:
struct RlvPredIsEqualOrLinkedItem
{
RlvPredIsEqualOrLinkedItem(const LLViewerInventoryItem* pItem) : m_pItem(pItem) {}
RlvPredIsEqualOrLinkedItem(const LLUUID& idItem) { m_pItem = gInventory.getItem(idItem); }
bool operator()(const LLViewerInventoryItem* pItem) const
{
return (m_pItem) && (pItem) && (m_pItem->getLinkedUUID() == pItem->getLinkedUUID());
}
RlvPredIsEqualOrLinkedItem(const LLUUID& idItem);
bool operator()(const LLViewerInventoryItem* pItem) const;
protected:
const LLViewerInventoryItem* m_pItem;
};
template<typename T> struct RlvPredValuesEqual
{
bool operator()(const T* pT2) const { return (pT1) && (pT2) && (*pT1 == *pT2); }
const T* pT1;
};
// ============================================================================
// Inlined class member functions
//

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -21,16 +21,10 @@
// Extensions
//
// Provides access to "advanced" features through the RLVa debug menu
#define RLV_EXTENSION_FLOATER_RESTRICTIONS // Enables the Advanced / RLVa / Restrictions... floater
#define RLV_EXTENSION_HIDELOCKED // "Hide locked layers", "Hide locked attachments" and "Hide locked inventory"
// Extensions
#define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx
#define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results
#define RLV_EXTENSION_FORCEWEAR_GESTURES // @attach*/detach* commands also (de)activate gestures
#define RLV_EXTENSION_GIVETORLV_A2A // Allow "Give to #RLV" on avatar-to-avatar inventory offers
#define RLV_EXTENSION_NOTIFY_BEHAVIOUR // Provides the option to show a customizable notification whenever a behaviour gets (un)set
#define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff
#define RLV_EXPERIMENTAL // Enables/disables experimental features en masse
#define RLV_EXPERIMENTAL_CMDS // Enables/disables experimental commands en masse
@ -45,7 +39,6 @@
// Under development (don't include in public release)
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// #define RLV_EXPERIMENTAL_COMPOSITEFOLDERS
// #define RLV_EXPERIMENTAL_FIRSTUSE // Enables a number of "first use" popups
#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
#endif // RLV_EXPERIMENTAL
@ -53,10 +46,9 @@
#ifdef RLV_EXPERIMENTAL_CMDS
#define RLV_EXTENSION_CMD_ALLOWIDLE // Forces "Away" status when idle (effect is the same as setting AllowIdleAFK to TRUE)
#define RLV_EXTENSION_CMD_GETCOMMAND // @getcommand:<option>=<channel>
// #define RLV_EXTENSION_CMD_GETXXXNAMES // @get[add|rem]attachnames:<option>=<channel> and @get[add|rem]outfitnames=<channel>
#define RLV_EXTENSION_CMD_GETXXXNAMES // @get[add|rem]attachnames:<option>=<channel> and @get[add|rem]outfitnames=<channel>
#define RLV_EXTENSION_CMD_INTERACT // @interact=n
#define RLV_EXTENSION_CMD_TOUCHXXX // @touch:uuid=n|y, @touchworld[:<uuid>]=n|y, @touchattach[:<uuid>]=n|y, @touchud[:<uuid>]=n|y
#define RLV_EXTENSION_CMD_DISPLAYNAME // @displayname=n
#endif // RLV_EXPERIMENTAL_CMDS
// ============================================================================
@ -65,23 +57,19 @@
// Version of the specifcation we support
const S32 RLV_VERSION_MAJOR = 2;
const S32 RLV_VERSION_MINOR = 2;
const S32 RLV_VERSION_MINOR = 7;
const S32 RLV_VERSION_PATCH = 0;
const S32 RLV_VERSION_BUILD = 1;
const S32 RLV_VERSION_BUILD = 0;
// Implementation version
const S32 RLVa_VERSION_MAJOR = 1;
const S32 RLVa_VERSION_MINOR = 3;
const S32 RLVa_VERSION_PATCH = 0;
const S32 RLVa_VERSION_BUILD = 4;
const S32 RLVa_VERSION_PATCH = 1;
const S32 RLVa_VERSION_BUILD = 1;
// Uncomment before a final release
//#define RLV_RELEASE
// The official viewer version we're patching against
#define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z)
#define RLV_TARGET RLV_MAKE_TARGET(2, 1, 2)
// Defining these makes it easier if we ever need to change our tag
#define RLV_WARNS LL_WARNS("RLV")
#define RLV_INFOS LL_INFOS("RLV")
@ -95,11 +83,7 @@ const S32 RLVa_VERSION_BUILD = 4;
// Make sure we halt execution on errors
#define RLV_ERRS LL_ERRS("RLV")
// Keep our asserts separate from LL's
#ifdef LL_WINDOWS
#define RLV_ASSERT(f) if (!(f)) { if (IsDebuggerPresent()) DebugBreak(); else { RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; } }
#else
#define RLV_ASSERT(f) if (!(f)) { RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; }
#endif // LL_WINDOWS
#define RLV_ASSERT(f) if (!(f)) { RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; }
#define RLV_ASSERT_DBG(f) RLV_ASSERT(f)
#else
// Don't halt execution on errors in release
@ -135,6 +119,10 @@ enum ERlvBehaviour {
RLV_BHVR_REMATTACH, // "remattach"
RLV_BHVR_ADDOUTFIT, // "addoutfit"
RLV_BHVR_REMOUTFIT, // "remoutfit"
RLV_BHVR_SHAREDWEAR, // "sharedwear"
RLV_BHVR_SHAREDUNWEAR, // "sharedunwear"
RLV_BHVR_UNSHAREDWEAR, // "unsharedwear"
RLV_BHVR_UNSHAREDUNWEAR, // "unsharedunwear"
RLV_BHVR_EMOTE, // "emote"
RLV_BHVR_SENDCHAT, // "sendchat"
RLV_BHVR_RECVCHAT, // "recvchat"
@ -151,6 +139,8 @@ enum ERlvBehaviour {
RLV_BHVR_SENDIMTO, // "sendimto"
RLV_BHVR_RECVIM, // "recvim"
RLV_BHVR_RECVIMFROM, // "recvimfrom"
RLV_BHVR_STARTIM, // "startim"
RLV_BHVR_STARTIMTO, // "startimto"
RLV_BHVR_PERMISSIVE, // "permissive"
RLV_BHVR_NOTIFY, // "notify"
RLV_BHVR_SHOWINV, // "showinv"
@ -171,37 +161,45 @@ enum ERlvBehaviour {
RLV_BHVR_ACCEPTPERMISSION, // "acceptpermission"
RLV_BHVR_ACCEPTTP, // "accepttp"
RLV_BHVR_ALLOWIDLE, // "allowidle"
RLV_BHVR_DISPLAYNAME, // "displayname"
RLV_BHVR_EDIT, // "edit"
RLV_BHVR_EDITOBJ, // "editobj"
RLV_BHVR_REZ, // "rez"
RLV_BHVR_FARTOUCH, // "fartouch"
RLV_BHVR_INTERACT, // "interact"
RLV_BHVR_TOUCHOBJ, // "touchobj"
RLV_BHVR_TOUCHTHIS, // "touchthis"
RLV_BHVR_TOUCHATTACH, // "touchattach"
RLV_BHVR_TOUCHATTACHSELF, // "touchattachself"
RLV_BHVR_TOUCHATTACHOTHER, // "touchattachother"
RLV_BHVR_TOUCHHUD, // "touchhud"
RLV_BHVR_TOUCHWORLD, // "touchworld"
RLV_BHVR_TOUCHALL, // "touchall"
RLV_BHVR_TOUCHME, // "touchme"
RLV_BHVR_FLY, // "fly"
RLV_BHVR_SETGROUP, // "setgroup"
RLV_BHVR_UNSIT, // "unsit"
RLV_BHVR_SIT, // "sit"
RLV_BHVR_SITTP, // "sittp"
RLV_BHVR_STANDTP, // "standtp"
RLV_BHVR_SETDEBUG, // "setdebug"
RLV_BHVR_SETENV, // "setenv"
RLV_BHVR_ALWAYSRUN, // "alwaysrun"
RLV_BHVR_TEMPRUN, // "temprun"
RLV_BHVR_DETACHME, // "detachme"
RLV_BHVR_ATTACHOVER, // "attachover"
RLV_BHVR_ATTACHTHIS, // "attachthis"
RLV_BHVR_ATTACHTHISOVER, // "attachthisover"
RLV_BHVR_ATTACHTHISEXCEPT, // "attachthisexcept"
RLV_BHVR_DETACHTHIS, // "detachthis"
RLV_BHVR_DETACHTHISEXCEPT, // "detachthisexcept"
RLV_BHVR_ATTACHALL, // "attachall"
RLV_BHVR_ATTACHALLOVER, // "attachallover"
RLV_BHVR_DETACHALL, // "detachall"
RLV_BHVR_ATTACHALLTHIS, // "attachallthis"
RLV_BHVR_ATTACHALLTHISEXCEPT, // "attachallthisexcept"
RLV_BHVR_ATTACHALLTHISOVER, // "attachallthisover"
RLV_BHVR_DETACHALLTHIS, // "detachallthis"
RLV_BHVR_DETACHALLTHISEXCEPT, // "detachallthisexcept"
RLV_BHVR_ADJUSTHEIGHT, // "adjustheight"
RLV_BHVR_TPTO, // "tpto"
RLV_BHVR_VERSION, // "version"
RLV_BHVR_VERSIONNEW, // "versionnew"
@ -220,6 +218,7 @@ enum ERlvBehaviour {
RLV_BHVR_GETPATHNEW, // "getpathnew"
RLV_BHVR_GETINV, // "getinv"
RLV_BHVR_GETINVWORN, // "getinvworn"
RLV_BHVR_GETGROUP, // "getgroup"
RLV_BHVR_GETSITID, // "getsitid"
RLV_BHVR_GETCOMMAND, // "getcommand"
RLV_BHVR_GETSTATUS, // "getstatus"
@ -239,12 +238,12 @@ enum ERlvParamType {
};
enum ERlvCmdRet {
RLV_RET_UNKNOWN = 0x0000, // Unknown error (should only be used internally)
RLV_RET_UNKNOWN = 0x0000, // Unknown error (should only be used internally)
RLV_RET_RETAINED, // Command was retained
RLV_RET_SUCCESS = 0x0100, // Command executed succesfully
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_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)
@ -263,17 +262,17 @@ enum ERlvExceptionCheck
enum ERlvLockMask
{
RLV_LOCK_ADD = 0x01,
RLV_LOCK_REMOVE = 0x02,
RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE
RLV_LOCK_ADD = 0x01,
RLV_LOCK_REMOVE = 0x02,
RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE
};
enum ERlvWearMask
{
RLV_WEAR_LOCKED = 0x00, // User can not wear the item at all
RLV_WEAR_ADD = 0x01, // User can wear the item in addition to what's already worn
RLV_WEAR_LOCKED = 0x00, // User can not wear the item at all
RLV_WEAR_ADD = 0x01, // User can wear the item in addition to what's already worn
RLV_WEAR_REPLACE = 0x02, // User can wear the item and replace what's currently worn
RLV_WEAR = 0x03 // Convenience: combines RLV_WEAR_ADD and RLV_WEAR_REPLACE
RLV_WEAR = 0x03 // Convenience: combines RLV_WEAR_ADD and RLV_WEAR_REPLACE
};
enum ERlvAttachGroupType
@ -314,7 +313,7 @@ enum ERlvAttachGroupType
#define RLV_SETTING_FIRSTUSE_GIVETORLV RLV_SETTING_FIRSTUSE_PREFIX"GiveToRLV"
// ============================================================================
// Strings
// Strings (see rlva_strings.xml)
//
#define RLV_STRING_HIDDEN "hidden_generic"
@ -325,6 +324,8 @@ enum ERlvAttachGroupType
#define RLV_STRING_BLOCKED_RECVIM "blocked_recvim"
#define RLV_STRING_BLOCKED_RECVIM_REMOTE "blocked_recvim_remote"
#define RLV_STRING_BLOCKED_SENDIM "blocked_sendim"
#define RLV_STRING_BLOCKED_STARTCONF "blocked_startconf"
#define RLV_STRING_BLOCKED_STARTIM "blocked_startim"
#define RLV_STRING_BLOCKED_TELEPORT "blocked_teleport"
#define RLV_STRING_BLOCKED_TPLURE_REMOTE "blocked_tplure_remote"
#define RLV_STRING_BLOCKED_VIEWXXX "blocked_viewxxx"

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,15 +15,15 @@
*/
#include "llviewerprecompiledheaders.h"
//#include "llagent.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
//#include "llviewerwindow.h"
//#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llwlparammanager.h"
#include "rlvextensions.h"
#include "rlvhandler.h"
#include "rlvhelper.h"
// ============================================================================

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,6 +15,8 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llavatarnamecache.h"
#include "llclipboard.h"
#include "llscrolllistctrl.h"
#include "llviewerjointattachment.h"
#include "llviewerobjectlist.h"
@ -43,46 +45,117 @@ std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt =
const LLViewerJointAttachment* pAttachPt =
get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL);
std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown");
return llformat("%s (%s, %s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "root" : "child");
return llformat("%s (%s%s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "" : ", child");
}
// Checked: 2011-05-23 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
bool rlvGetShowException(ERlvBehaviour eBhvr)
{
switch (eBhvr)
{
case RLV_BHVR_RECVCHAT:
case RLV_BHVR_RECVEMOTE:
case RLV_BHVR_SENDIM:
case RLV_BHVR_RECVIM:
case RLV_BHVR_STARTIM:
case RLV_BHVR_TPLURE:
case RLV_BHVR_ACCEPTTP:
return true;
default:
return false;
}
}
// ============================================================================
// RlvFloaterLocks member functions
// RlvFloaterBehaviours member functions
//
// Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onOpen(const LLSD& sdKey)
{
m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterBehaviours::onRlvCommand, this, _1, _2));
m_ConnRlvCommand = gRlvHandler.setCommandCallback(boost::bind(&RlvFloaterBehaviours::onCommand, this, _1, _2));
refreshAll();
}
// Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onClose(bool fQuitting)
{
m_ConnRlvCommand.disconnect();
// LLFloaterPay::~LLFloaterPay(): Name callbacks will be automatically disconnected since LLFloater is trackable <- how does that work?
}
// Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onRlvCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
// Checked: 2010-04-18 (RLVa-1.3.1c) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName)
{
// Refresh on any successful @XXX=y|n command
if ( (RLV_RET_SUCCESS == eRet) && ((RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType())) )
{
uuid_vec_t::iterator itLookup = std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idAgent);
if (itLookup != m_PendingLookup.end())
m_PendingLookup.erase(itLookup);
if (getVisible())
refreshAll();
}
}
// Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
// Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
void RlvFloaterBehaviours::onBtnCopyToClipboard()
{
std::ostringstream strRestrictions;
strRestrictions << RlvStrings::getVersion() << "\n";
const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
{
strRestrictions << "\n" << rlvGetItemNameFromObjID(itObj->first) << ":\n";
const rlv_command_list_t* pCommands = itObj->second.getCommandList();
for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
{
std::string strOption; LLUUID idOption;
if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) )
{
LLAvatarName avName;
if (gObjectList.findObject(idOption))
strOption = rlvGetItemNameFromObjID(idOption, true);
else if (LLAvatarNameCache::get(idOption, &avName))
strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName;
else if (!gCacheName->getGroupName(idOption, strOption))
strOption = itCmd->getOption();
}
strRestrictions << " -> " << itCmd->asString();
if ( (!strOption.empty()) && (strOption != itCmd->getOption()) )
strRestrictions << " [" << strOption << "]";
if (RLV_RET_SUCCESS != itCmd->getReturnType())
strRestrictions << " (" << RlvStrings::getStringFromReturnCode(itCmd->getReturnType()) << ")";
strRestrictions << "\n";
}
}
gClipboard.copyFromString(utf8str_to_wstring(strRestrictions.str()));
}
// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
if ( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) )
refreshAll();
}
// Checked: 2011-05-23 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
BOOL RlvFloaterBehaviours::postBuild()
{
getChild<LLUICtrl>("copy_btn")->setCommitCallback(boost::bind(&RlvFloaterBehaviours::onBtnCopyToClipboard, this));
return TRUE;
}
// Checked: 2011-05-23 (RLVa-1.3.1c) | Modified: RLVa-1.3.1c
void RlvFloaterBehaviours::refreshAll()
{
LLCtrlListInterface* pBhvrList = childGetListInterface("behaviour_list");
if (!pBhvrList)
LLCtrlListInterface* pExceptList = childGetListInterface("exception_list");
if ( (!pBhvrList) || (!pExceptList) )
return;
pBhvrList->operateOnAll(LLCtrlListInterface::OP_DELETE);
pExceptList->operateOnAll(LLCtrlListInterface::OP_DELETE);
if (!isAgentAvatarValid())
return;
@ -90,58 +163,70 @@ void RlvFloaterBehaviours::refreshAll()
//
// Set-up a row we can just reuse
//
LLSD sdRow;
LLSD& sdColumns = sdRow["columns"];
sdColumns[0]["column"] = "behaviour"; sdColumns[0]["type"] = "text";
sdColumns[1]["column"] = "name"; sdColumns[1]["type"] = "text";
LLSD sdBhvrRow; LLSD& sdBhvrColumns = sdBhvrRow["columns"];
sdBhvrColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
sdBhvrColumns[1] = LLSD().with("column", "issuer").with("type", "text");
LLSD sdExceptRow; LLSD& sdExceptColumns = sdExceptRow["columns"];
sdExceptColumns[0] = LLSD().with("column", "behaviour").with("type", "text");
sdExceptColumns[1] = LLSD().with("column", "option").with("type", "text");
sdExceptColumns[2] = LLSD().with("column", "issuer").with("type", "text");
//
// List behaviours
//
const RlvHandler::rlv_object_map_t* pRlvObjects = gRlvHandler.getObjectMap();
for (RlvHandler::rlv_object_map_t::const_iterator itObj = pRlvObjects->begin(), endObj = pRlvObjects->end(); itObj != endObj; ++itObj)
const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap();
for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj)
{
sdColumns[1]["value"] = rlvGetItemNameFromObjID(itObj->first);
const std::string strIssuer = rlvGetItemNameFromObjID(itObj->first);
const rlv_command_list_t* pCommands = itObj->second.getCommandList();
for (rlv_command_list_t::const_iterator itCmd = pCommands->begin(), endCmd = pCommands->end(); itCmd != endCmd; ++itCmd)
{
std::string strBhvr = itCmd->asString();
LLUUID idOption(itCmd->getOption());
if (idOption.notNull())
std::string strOption; LLUUID idOption;
if ( (itCmd->hasOption()) && (idOption.set(itCmd->getOption(), FALSE)) && (idOption.notNull()) )
{
std::string strLookup;
if ( (gCacheName->getFullName(idOption, strLookup)) || (gCacheName->getGroupName(idOption, strLookup)) )
LLAvatarName avName;
if (gObjectList.findObject(idOption))
{
if (strLookup.find("???") == std::string::npos)
strBhvr.assign(itCmd->getBehaviour()).append(":").append(strLookup);
strOption = rlvGetItemNameFromObjID(idOption, true);
}
else if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption))
else if (LLAvatarNameCache::get(idOption, &avName))
{
gCacheName->get(idOption, FALSE, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2, _3));
m_PendingLookup.push_back(idOption);
strOption = (!avName.mUsername.empty()) ? avName.mUsername : avName.mDisplayName;
}
else if (!gCacheName->getGroupName(idOption, strOption))
{
if (m_PendingLookup.end() == std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idOption))
{
LLAvatarNameCache::get(idOption, boost::bind(&RlvFloaterBehaviours::onAvatarNameLookup, this, _1, _2));
m_PendingLookup.push_back(idOption);
}
strOption = itCmd->getOption();
}
}
sdColumns[0]["value"] = strBhvr;
pBhvrList->addElement(sdRow, ADD_BOTTOM);
if ( (itCmd->hasOption()) && (rlvGetShowException(itCmd->getBehaviourType())) )
{
// List under the "Exception" tab
sdExceptRow["enabled"] = gRlvHandler.isException(itCmd->getBehaviourType(), idOption);
sdExceptColumns[0]["value"] = itCmd->getBehaviour();
sdExceptColumns[1]["value"] = strOption;
sdExceptColumns[2]["value"] = strIssuer;
pExceptList->addElement(sdExceptRow, ADD_BOTTOM);
}
else
{
// List under the "Restrictions" tab
sdBhvrRow["enabled"] = (RLV_RET_SUCCESS == itCmd->getReturnType());
sdBhvrColumns[0]["value"] = (strOption.empty()) ? itCmd->asString() : itCmd->getBehaviour() + ":" + strOption;
sdBhvrColumns[1]["value"] = strIssuer;
pBhvrList->addElement(sdBhvrRow, ADD_BOTTOM);
}
}
}
}
// Checked: 2010-04-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0e
void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const std::string& strFullname, BOOL fGroup)
{
std::list<LLUUID>::iterator itLookup = std::find(m_PendingLookup.begin(), m_PendingLookup.end(), idAgent);
if (itLookup != m_PendingLookup.end())
m_PendingLookup.erase(itLookup);
if (getVisible())
refreshAll();
}
// ============================================================================
// RlvFloaterLocks member functions
//

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -36,28 +36,25 @@ private:
* LLFloater overrides
*/
public:
virtual void onOpen(const LLSD& sdKey);
virtual void onClose(bool fQuitting);
/*
* Event handlers
*/
protected:
void onRlvCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet);
void onAvatarNameLookup(const LLUUID& idAgent, const std::string& strFullname, BOOL fGroup);
/*virtual*/ void onOpen(const LLSD& sdKey);
/*virtual*/ void onClose(bool fQuitting);
/*virtual*/ BOOL postBuild();
/*
* Member functions
*/
protected:
void onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName);
void onBtnCopyToClipboard();
void onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet);
void refreshAll();
/*
* Member variables
*/
protected:
boost::signals2::connection m_ConnRlvCommand;
std::list<LLUUID> m_PendingLookup;
boost::signals2::connection m_ConnRlvCommand;
uuid_vec_t m_PendingLookup;
};
// ============================================================================

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,11 +15,12 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llagentwearables.h"
#include "llagent.h"
#include "llappearancemgr.h"
#include "llappviewer.h"
#include "llcallbacklist.h"
#include "llgroupactions.h"
#include "llhudtext.h"
#include "llstartup.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
@ -31,6 +32,8 @@
#include "rlvui.h"
#include "rlvextensions.h"
#include <boost/algorithm/string.hpp>
// ============================================================================
// Static variable initialization
//
@ -71,6 +74,8 @@ static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, st
// Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.1d
RlvHandler::RlvHandler() : m_fCanCancelTp(true), m_posSitSource(), m_pGCTimer(NULL), m_pWLSnapshot(NULL)
{
gAgent.addListener(this, "new group");
// Array auto-initialization to 0 is non-standard? (Compiler warning in VC-8.0)
memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT);
}
@ -78,6 +83,8 @@ RlvHandler::RlvHandler() : m_fCanCancelTp(true), m_posSitSource(), m_pGCTimer(NU
// Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.1d
RlvHandler::~RlvHandler()
{
gAgent.removeListener(this);
//delete m_pGCTimer; // <- deletes itself
delete m_pWLSnapshot; // <- delete on NULL is harmless
}
@ -86,14 +93,33 @@ RlvHandler::~RlvHandler()
// Behaviour related functions
//
bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const
bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBhvr, const std::string& strOption, const LLUUID& idObj) const
{
for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
if ( (idObj != itObj->second.getObjectID()) && (itObj->second.hasBehaviour(eBehaviour, strOption, false)) )
if ( (idObj != itObj->second.getObjectID()) && (itObj->second.hasBehaviour(eBhvr, strOption, false)) )
return true;
return false;
}
// Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
bool RlvHandler::hasBehaviourRoot(const LLUUID& idObjRoot, ERlvBehaviour eBhvr, const std::string& strOption) const
{
for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
if ( (idObjRoot == itObj->second.getRootID()) && (itObj->second.hasBehaviour(eBhvr, strOption, false)) )
return true;
return false;
}
// ============================================================================
// Behaviour exception handling
//
// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
void RlvHandler::addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
{
m_Exceptions.insert(std::pair<ERlvBehaviour, RlvException>(eBhvr, RlvException(idObj, eBhvr, varOption)));
}
// Checked: 2009-10-04 (RLVa-1.0.4c) | Modified: RLVa-1.0.4c
bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varOption, ERlvExceptionCheck typeCheck) const
{
@ -130,6 +156,28 @@ bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varO
return false;
}
// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
{
return (RlvCommand::hasStrictVariant(eBhvr))
? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE)))
: true;
}
// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
{
for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(eBhvr),
endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException)
{
if ( (itException->second.idObject == idObj) && (itException->second.varOption == varOption) )
{
m_Exceptions.erase(itException);
break;
}
}
}
// ============================================================================
// Command processing functions
//
@ -233,6 +281,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
if (!m_pGCTimer)
m_pGCTimer = new RlvGCTimer();
eRet = processAddRemCommand(rlvCmd);
m_Objects.find(idCurObj)->second.setCommandRet(rlvCmd, eRet); // HACK-RLVa: find a better way of doing this
// notifyBehaviourObservers(rlvCmd, !fFromObj);
}
else
@ -296,6 +345,17 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
return eRet;
}
// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj)
{
if (STATE_STARTED != LLStartUp::getStartupState())
{
m_Retained.push_back(RlvCommand(idObj, strCommand));
return RLV_RET_RETAINED;
}
return processCommand(RlvCommand(idObj, strCommand), fFromObj);
}
// Checked: 2010-02-27 (RLVa-1.2.0a) | Modified: RLVa-1.1.0f
void RlvHandler::processRetainedCommands(ERlvBehaviour eBhvrFilter /*=RLV_BHVR_UNKNOWN*/, ERlvParamType eTypeFilter /*=RLV_TYPE_UNKNOWN*/)
{
@ -347,6 +407,25 @@ ERlvCmdRet RlvHandler::processClearCommand(const RlvCommand& rlvCmd)
// Externally invoked event handlers
//
// Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
bool RlvHandler::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& sdUserdata)
{
// If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one
if ( (hasBehaviour(RLV_BHVR_SETGROUP)) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) )
{
// [Copy/paste from LLGroupActions::activate()]
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, m_idAgentGroup);
gAgent.sendReliableMessage();
return true;
}
return false;
}
// Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
void RlvHandler::onSitOrStand(bool fSitting)
{
@ -571,16 +650,39 @@ void RlvHandler::onTeleportFinished(const LLVector3d& posArrival)
// String/chat censoring functions
//
// Checked: 2010-01-21 (RLVa-1.3.0e) | Modified: RLVa-1.3.0e
// Checked: 2010-03-06 (RLVa-1.2.0c) | Added: RLVa-1.1.0j
bool RlvHandler::canSit(LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/) const
{
// The user can sit on the specified object if:
// - not prevented from sitting
// - not prevented from standing up or not currently sitting
// - not standtp restricted or not currently sitting (if the user is sitting and tried to sit elsewhere the tp would just kick in)
// - [regular sit] not @sittp=n or @fartouch=n restricted or if they clicked on a point within 1.5m of the avie's current position
// - [force sit] not @sittp=n restricted by a *different* object than the one that issued the command or the object is within 1.5m
return
( (pObj) && (LL_PCODE_VOLUME == pObj->getPCode()) ) &&
(!hasBehaviour(RLV_BHVR_SIT)) &&
( ((!hasBehaviour(RLV_BHVR_UNSIT)) && (!hasBehaviour(RLV_BHVR_STANDTP))) ||
((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting())) ) &&
( ((NULL == getCurrentCommand() || (RLV_BHVR_SIT != getCurrentCommand()->getBehaviourType()))
? ((!hasBehaviour(RLV_BHVR_SITTP)) && (!hasBehaviour(RLV_BHVR_FARTOUCH))) // [regular sit]
: (!hasBehaviourExcept(RLV_BHVR_SITTP, getCurrentObject()))) || // [force sit]
(dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < 1.5f * 1.5f) );
}
// Checked: 2010-03-07 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
bool RlvHandler::canStand() const
{
// NOTE: return FALSE only if we're @unsit=n restricted and the avie is currently sitting on something and TRUE for everything else
return (!hasBehaviour(RLV_BHVR_UNSIT)) || ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting()));
}
// Checked: 2010-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h
bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) const
{
const LLUUID& idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null;
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
bool fCanTouch = (idRoot.notNull()) && ((!pObj->isHUDAttachment()) || (!hasBehaviour(RLV_BHVR_TOUCHALL))) &&
((!hasBehaviour(RLV_BHVR_TOUCHOBJ)) || (!isException(RLV_BHVR_TOUCHOBJ, idRoot, RLV_CHECK_PERMISSIVE)));
#else
bool fCanTouch = (idRoot.notNull()) && ((!pObj->isHUDAttachment()) || (!hasBehaviour(RLV_BHVR_TOUCHALL)));
#endif // RLV_EXTENSION_CMD_TOUCHXXX
((!hasBehaviour(RLV_BHVR_TOUCHTHIS)) || (!isException(RLV_BHVR_TOUCHTHIS, idRoot, RLV_CHECK_PERMISSIVE)));
if (fCanTouch)
{
@ -608,6 +710,8 @@ bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
}
#endif // RLV_EXTENSION_CMD_TOUCHXXX
}
if ( (!fCanTouch) && (hasBehaviour(RLV_BHVR_TOUCHME)) )
fCanTouch = hasBehaviourRoot(idRoot, RLV_BHVR_TOUCHME);
return fCanTouch;
}
@ -676,6 +780,12 @@ void RlvHandler::filterChat(std::string& strUTF8Text, bool fFilterEmote) const
}
}
// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
bool RlvHandler::hasException(ERlvBehaviour eBhvr) const
{
return (m_Exceptions.find(eBhvr) != m_Exceptions.end());
}
// Checked: 2010-02-27 (RLVa-1.2.0b) | Modified: RLVa-1.2.0a
bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const
{
@ -1022,6 +1132,12 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_DETACHALLTHIS: // @detachallthis[:<option>]=n|y
eRet = onAddRemFolderLock(rlvCmd, fRefCount);
break;
case RLV_BHVR_ATTACHTHISEXCEPT: // @attachthisexcept[:<option>]=n|y
case RLV_BHVR_DETACHTHISEXCEPT: // @detachthisexcept[:<option>]=n|y
case RLV_BHVR_ATTACHALLTHISEXCEPT: // @attachallthisexcept[:<option>]=n|y
case RLV_BHVR_DETACHALLTHISEXCEPT: // @detachallthisexcept[:<option>]=n|y
eRet = onAddRemFolderLockException(rlvCmd, fRefCount);
break;
case RLV_BHVR_SETENV: // @setenv=n|y
eRet = onAddRemSetEnv(rlvCmd, fRefCount);
break;
@ -1049,6 +1165,44 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
}
}
break;
case RLV_BHVR_SHAREDWEAR: // @sharedwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
case RLV_BHVR_SHAREDUNWEAR: // @sharedunwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
{
VERIFY_OPTION_REF(strOption.empty());
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_SHAREDPATH, LLStringUtil::null);
RlvFolderLocks::ELockScope eLockScope = RlvFolderLocks::SCOPE_SUBTREE;
ERlvLockMask eLockType = (RLV_BHVR_SHAREDUNWEAR == eBhvr) ? RLV_LOCK_REMOVE : RLV_LOCK_ADD;
if (RLV_TYPE_ADD == eType)
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
else
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
}
break;
case RLV_BHVR_UNSHAREDWEAR: // @unsharedwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
case RLV_BHVR_UNSHAREDUNWEAR: // @unsharedunwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
{
VERIFY_OPTION_REF(strOption.empty());
// Lock down the inventory root
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_ROOTFOLDER, 0);
RlvFolderLocks::ELockScope eLockScope = RlvFolderLocks::SCOPE_SUBTREE;
ERlvLockMask eLockType = (RLV_BHVR_UNSHAREDUNWEAR == eBhvr) ? RLV_LOCK_REMOVE : RLV_LOCK_ADD;
if (RLV_TYPE_ADD == eType)
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
else
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
// Add the #RLV shared folder as an exception
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_SHAREDPATH, LLStringUtil::null);
if (RLV_TYPE_ADD == eType)
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_ALLOW, eLockScope, rlvCmd.getObjectID(), eLockType);
else
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_ALLOW, eLockScope, rlvCmd.getObjectID(), eLockType);
}
break;
case RLV_BHVR_REDIRCHAT: // @redirchat:<channel>=n|y - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h
case RLV_BHVR_REDIREMOTE: // @rediremote:<channel>=n|y - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h
{
@ -1089,6 +1243,14 @@ 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.3.1b) | 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
@ -1106,6 +1268,22 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getObjectText());
}
break;
case RLV_BHVR_ALWAYSRUN: // @alwaysrun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
{
VERIFY_OPTION_REF(strOption.empty());
if (RLV_TYPE_ADD == eType)
gAgent.clearAlwaysRun();
}
break;
case RLV_BHVR_TEMPRUN: // @temprun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
{
VERIFY_OPTION_REF(strOption.empty());
if (RLV_TYPE_ADD == eType)
gAgent.clearTempRun();
}
break;
// The following block is only valid if there's no option
case RLV_BHVR_SHOWLOC: // @showloc=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_SHOWNAMES: // @shownames=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
@ -1131,9 +1309,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
case RLV_BHVR_ALLOWIDLE: // @allowidle=n|y - Checked: 2010-05-03 (RLVa-1.2.0g) | Modified: RLVa-1.1.0h
#endif // RLV_EXTENSION_CMD_ALLOWIDLE
#ifdef RLV_EXTENSION_CMD_DISPLAYNAME
case RLV_BHVR_DISPLAYNAME: // @displayname=n|y - Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
#endif // RLV_EXTENSION_CMD_DISPLAYNAME
case RLV_BHVR_REZ: // @rez=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_FARTOUCH: // @fartouch=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
#ifdef RLV_EXTENSION_CMD_INTERACT
@ -1142,6 +1317,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_TOUCHATTACHSELF: // @touchattachself=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
case RLV_BHVR_TOUCHATTACHOTHER: // @touchattachother=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
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_UNSIT: // @unsit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_SIT: // @sit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
@ -1154,6 +1330,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_RECVEMOTE: // @recvemote[:<uuid>]=n|y - Checked: 2010-03-26 (RLVa-1.2.0b)
case RLV_BHVR_SENDIM: // @sendim[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_RECVIM: // @recvim[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_STARTIM: // @startim[:<uuid>]=n|y - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
case RLV_BHVR_TPLURE: // @tplure[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_ACCEPTTP: // @accepttp[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
case RLV_BHVR_TOUCHATTACH: // @touchattach[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
@ -1182,10 +1359,9 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_RECVEMOTEFROM: // @recvemotefrom:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
case RLV_BHVR_SENDIMTO: // @sendimto:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
case RLV_BHVR_RECVIMFROM: // @recvimfrom:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
case RLV_BHVR_STARTIMTO: // @startimto:<uuid>=n|y - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
case RLV_BHVR_EDITOBJ: // @editobj:<uuid>=n|y - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
case RLV_BHVR_TOUCHOBJ: // @touchobj:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
#endif // RLV_EXTENSION_CMD_TOUCHXXX
case RLV_BHVR_TOUCHTHIS: // @touchthis:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
{
// There should be an option and it should specify a valid UUID
LLUUID idException(strOption);
@ -1226,16 +1402,8 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
}
m_OnBehaviour(eBhvr, eType);
// Show an - optional - notification on every global behaviour change
#ifdef RLV_EXTENSION_NOTIFY_BEHAVIOUR
/*
if ( ((RLV_TYPE_ADD == eType) && (1 == m_Behaviours[eBhvr])) || (0 == m_Behaviours[eBhvr]) )
{
RlvNotifications::notifyBehaviour(eBhvr, eType);
}
*/
#endif // RLV_EXTENSION_NOTIFY_BEHAVIOUR
if ( ((RLV_TYPE_ADD == eType) && (1 == m_Behaviours[eBhvr])) || ((RLV_TYPE_REMOVE == eType) && (0 == m_Behaviours[eBhvr])) )
m_OnBehaviourToggle(eBhvr, eType);
}
return eRet;
@ -1322,25 +1490,24 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount)
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
ERlvCmdRet RlvHandler::onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCount)
{
RlvFolderLocks::rlv_folderlock_source_t lockSource;
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
RlvFolderLocks::folderlock_source_t lockSource;
if (rlvCmdOption.isEmpty())
{
lockSource = rlvCmd.getObjectID();
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_ATTACHMENT, rlvCmd.getObjectID());
}
else if (rlvCmdOption.isSharedFolder())
{
lockSource = rlvCmd.getOption();
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_SHAREDPATH, rlvCmd.getOption());
}
else if (rlvCmdOption.isAttachmentPoint())
{
lockSource = RlvAttachPtLookup::getAttachPointIndex(rlvCmdOption.getAttachmentPoint());
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_ATTACHMENTPOINT, RlvAttachPtLookup::getAttachPointIndex(rlvCmdOption.getAttachmentPoint()));
}
else if (rlvCmdOption.isWearableType())
{
lockSource = rlvCmdOption.getWearableType();
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_WEARABLETYPE, rlvCmdOption.getWearableType());
}
else
{
@ -1350,12 +1517,47 @@ ERlvCmdRet RlvHandler::onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCo
ERlvBehaviour eBhvr = rlvCmd.getBehaviourType();
ERlvLockMask eLock = ((RLV_BHVR_ATTACHTHIS == eBhvr) || (RLV_BHVR_ATTACHALLTHIS == eBhvr)) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE;
RlvFolderLocks::rlv_folderlock_descr_t lockDescr(lockSource, ((RLV_BHVR_ATTACHALLTHIS == eBhvr) || (RLV_BHVR_DETACHALLTHIS == eBhvr)));
// Determine the lock type
ERlvLockMask eLockType = ((RLV_BHVR_ATTACHTHIS == eBhvr) || (RLV_BHVR_ATTACHALLTHIS == eBhvr)) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE;
// Determine the folder lock options from the issued behaviour
RlvFolderLocks::ELockPermission eLockPermission = RlvFolderLocks::PERM_DENY;
RlvFolderLocks::ELockScope eLockScope =
((RLV_BHVR_ATTACHALLTHIS == eBhvr) || (RLV_BHVR_DETACHALLTHIS == eBhvr)) ? RlvFolderLocks::SCOPE_SUBTREE : RlvFolderLocks::SCOPE_NODE;
if (RLV_TYPE_ADD == rlvCmd.getParamType())
RlvFolderLocks::instance().addFolderLock(lockDescr, rlvCmd.getObjectID(), eLock);
RlvFolderLocks::instance().addFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
else
RlvFolderLocks::instance().removeFolderLock(lockDescr, rlvCmd.getObjectID(), eLock);
RlvFolderLocks::instance().removeFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
fRefCount = true;
return RLV_RET_SUCCESS;
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
ERlvCmdRet RlvHandler::onAddRemFolderLockException(const RlvCommand& rlvCmd, bool& fRefCount)
{
// Sanity check - the option should specify a shared folder path
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
if (!rlvCmdOption.isSharedFolder())
return RLV_RET_FAILED_OPTION;
ERlvBehaviour eBhvr = rlvCmd.getBehaviourType();
// Determine the lock type
ERlvLockMask eLockType =
((RLV_BHVR_ATTACHTHISEXCEPT == eBhvr) || (RLV_BHVR_ATTACHALLTHISEXCEPT == eBhvr)) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE;
// Determine the folder lock options from the issued behaviour
RlvFolderLocks::ELockPermission eLockPermission = RlvFolderLocks::PERM_ALLOW;
RlvFolderLocks::ELockScope eLockScope =
((RLV_BHVR_ATTACHALLTHISEXCEPT == eBhvr) || (RLV_BHVR_DETACHALLTHISEXCEPT == eBhvr)) ? RlvFolderLocks::SCOPE_SUBTREE : RlvFolderLocks::SCOPE_NODE;
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_SHAREDPATH, rlvCmd.getOption());
if (RLV_TYPE_ADD == rlvCmd.getParamType())
RlvFolderLocks::instance().addFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
else
RlvFolderLocks::instance().removeFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
fRefCount = true;
return RLV_RET_SUCCESS;
@ -1421,6 +1623,9 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
eRet = onForceRemOutfit(rlvCmd);
}
break;
case RLV_BHVR_SETGROUP: // @setgroup:<uuid|name>=force - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
eRet = onForceGroup(rlvCmd);
break;
case RLV_BHVR_UNSIT: // @unsit=force - Checked: 2010-03-18 (RLVa-1.2.0c) | Modified: RLVa-0.2.0g
{
VERIFY_OPTION(rlvCmd.getOption().empty());
@ -1434,28 +1639,25 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_SIT: // @sit:<option>=force
eRet = onForceSit(rlvCmd);
break;
case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.0h
case RLV_BHVR_ADJUSTHEIGHT: // @adjustheight:<options>=force - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
{
eRet = RLV_RET_FAILED_OPTION;
if ( (!rlvCmd.getOption().empty()) && (std::string::npos == rlvCmd.getOption().find_first_not_of("0123456789/.")) )
RlvCommandOptionAdjustHeight rlvCmdOption(rlvCmd);
VERIFY_OPTION(rlvCmdOption.isValid());
if (isAgentAvatarValid())
{
LLVector3d posGlobal;
boost_tokenizer tokens(rlvCmd.getOption(), boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0;
for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
{
if (idx < 3)
LLStringUtil::convertToF64(*itToken, posGlobal[idx++]);
}
if (idx == 3)
{
gAgent.teleportViaLocation(posGlobal);
eRet = RLV_RET_SUCCESS;
}
F32 nValue = (rlvCmdOption.m_nPelvisToFoot - gAgentAvatarp->getPelvisToFoot()) * rlvCmdOption.m_nPelvisToFootDeltaMult;
nValue += rlvCmdOption.m_nPelvisToFootOffset;
gSavedSettings.setF32(RLV_SETTING_AVATAROFFSET_Z, llclamp<F32>(nValue, -1.0f, 1.0f));
}
}
break;
case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2011-03-28 (RLVa-1.3.0f) | Modified: RLVa-1.3.0f
{
RlvCommandOptionTpTo rlvCmdOption(rlvCmd);
VERIFY_OPTION( (rlvCmdOption.isValid()) && (!rlvCmdOption.m_posGlobal.isNull()) );
gAgent.teleportViaLocation(rlvCmdOption.m_posGlobal);
}
break;
case RLV_BHVR_ATTACH:
case RLV_BHVR_ATTACHOVER:
case RLV_BHVR_ATTACHALL:
@ -1558,6 +1760,31 @@ ERlvCmdRet RlvHandler::onForceRemOutfit(const RlvCommand& rlvCmd) const
return RLV_RET_SUCCESS;
}
// Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
ERlvCmdRet RlvHandler::onForceGroup(const RlvCommand& rlvCmd) const
{
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
LLUUID idGroup; bool fValid = false;
if (rlvCmdOption.isUUID())
{
idGroup = rlvCmdOption.getUUID();
fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true));
}
else if (rlvCmdOption.isString())
{
for (S32 idxGroup = 0, cntGroup = gAgent.mGroups.count(); (idxGroup < cntGroup) && (idGroup.isNull()); idxGroup++)
if (boost::iequals(gAgent.mGroups.get(idxGroup).mName, rlvCmd.getOption()))
idGroup = gAgent.mGroups.get(idxGroup).mID;
fValid = (idGroup.notNull()) || ("none" == rlvCmd.getOption());
}
if (fValid)
LLGroupActions::activate(idGroup);
return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION;
}
// Checked: 2010-03-18 (RLVa-1.2.0c) | Modified: RLVa-1.1.0j
ERlvCmdRet RlvHandler::onForceSit(const RlvCommand& rlvCmd) const
{
@ -1652,7 +1879,7 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_GETATTACHNAMES: // @getattachnames[:<grp>]=<channel>
case RLV_BHVR_GETADDATTACHNAMES:// @getaddattachnames[:<grp>]=<channel>
case RLV_BHVR_GETREMATTACHNAMES:// @getremattachnames[:<grp>]=<channel>
eRet = onGetAttachNames(idObj, rlvCmd, strReply);
eRet = onGetAttachNames(rlvCmd, strReply);
break;
#endif // RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_GETOUTFIT: // @getoutfit[:<layer>]=<channel>
@ -1662,7 +1889,7 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_GETOUTFITNAMES: // @getoutfitnames=<channel>
case RLV_BHVR_GETADDOUTFITNAMES:// @getaddoutfitnames=<channel>
case RLV_BHVR_GETREMOUTFITNAMES:// @getremoutfitnames=<channel>
eRet = onGetOutfitNames(idObj, rlvCmd, strReply);
eRet = onGetOutfitNames(rlvCmd, strReply);
break;
#endif // RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel>
@ -1681,6 +1908,9 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_GETINVWORN: // @getinvworn[:<path>]=<channel>
eRet = onGetInvWorn(rlvCmd, strReply);
break;
case RLV_BHVR_GETGROUP: // @getgroup=<channel> - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
strReply = (gAgent.getGroupID().notNull()) ? gAgent.getGroupName() : "none";
break;
case RLV_BHVR_GETSITID: // @getsitid=<channel> - Checked: 2010-03-09 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
{
// NOTE: RLV-1.16.1 returns a NULL UUID if we're not sitting

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -18,18 +18,12 @@
#define RLV_HANDLER_H
#include <stack>
#include "llagentconstants.h"
#include "llstartup.h"
#include "llviewerjointattachment.h"
#include "llviewerobject.h"
#include "rlvcommon.h"
#include "rlvhelper.h"
#include "rlvlocks.h"
// ============================================================================
class RlvHandler
class RlvHandler : public LLOldEvents::LLSimpleListener
{
public:
RlvHandler();
@ -48,11 +42,13 @@ public:
// - to check exceptions -> isException()
public:
// Returns TRUE is at least one object contains the specified behaviour (and optional option)
bool hasBehaviour(ERlvBehaviour eBehaviour) const { return (eBehaviour < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBehaviour]) : false; }
bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const;
bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; }
bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const;
// Returns TRUE if at least one object (except the specified one) contains the specified behaviour (and optional option)
bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const;
bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const;
bool hasBehaviourExcept(ERlvBehaviour eBhvr, const LLUUID& idObj) const;
bool hasBehaviourExcept(ERlvBehaviour eBhvr, const std::string& strOption, const LLUUID& idObj) const;
// Returns TRUE if at least one object in the linkset with specified root ID contains the specified behaviour (and optional option)
bool hasBehaviourRoot(const LLUUID& idObjRoot, ERlvBehaviour eBhvr, const std::string& strOption = LLStringUtil::null) const;
// Adds or removes an exception for the specified behaviour
void addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption);
@ -99,6 +95,7 @@ public:
bool canShowHoverText(const LLViewerObject* pObj) const; // @showhovertext* command family
bool canSendIM(const LLUUID& idRecipient) const; // @sendim and @sendimto
bool canSit(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const;
bool canStartIM(const LLUUID& idRecipient) const; // @startim and @startimto
bool canStand() const;
bool canTeleportViaLure(const LLUUID& idAgent) const;
bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const; // @touch
@ -129,10 +126,11 @@ protected:
public:
// The behaviour signal is triggered whenever a command is successfully processed and resulted in adding or removing a behaviour
typedef boost::signals2::signal<void (ERlvBehaviour, ERlvParamType)> rlv_behaviour_signal_t;
boost::signals2::connection setBehaviourCallback(const rlv_behaviour_signal_t::slot_type& cb ) { return m_OnBehaviour.connect(cb); }
boost::signals2::connection setBehaviourCallback(const rlv_behaviour_signal_t::slot_type& cb ) { return m_OnBehaviour.connect(cb); }
boost::signals2::connection setBehaviourToggleCallback(const rlv_behaviour_signal_t::slot_type& cb ) { return m_OnBehaviourToggle.connect(cb); }
// The command signal is triggered whenever a command is processed
typedef boost::signals2::signal<void (const RlvCommand&, ERlvCmdRet, bool)> rlv_command_signal_t;
boost::signals2::connection setCommandCallback(const rlv_command_signal_t::slot_type& cb ) { return m_OnCommand.connect(cb); }
boost::signals2::connection setCommandCallback(const rlv_command_signal_t::slot_type& cb ) { return m_OnCommand.connect(cb); }
void addCommandHandler(RlvCommandHandler* pHandler);
void removeCommandHandler(RlvCommandHandler* pHandler);
@ -142,6 +140,7 @@ protected:
// Externally invoked event handlers
public:
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& sdUserdata); // Implementation of public LLSimpleListener
void onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt);
void onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt);
bool onGC();
@ -163,11 +162,13 @@ protected:
ERlvCmdRet onAddRemAttach(const RlvCommand& rlvCmd, bool& fRefCount);
ERlvCmdRet onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount);
ERlvCmdRet onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCount);
ERlvCmdRet onAddRemFolderLockException(const RlvCommand& rlvCmd, bool& fRefCount);
ERlvCmdRet onAddRemSetEnv(const RlvCommand& rlvCmd, bool& fRefCount);
// Command handlers (RLV_TYPE_FORCE)
ERlvCmdRet processForceCommand(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceRemAttach(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceRemOutfit(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceGroup(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceSit(const RlvCommand& rlvCmd) const;
ERlvCmdRet onForceWear(const LLViewerInventoryCategory* pFolder, ERlvBehaviour eBhvr) const;
// Command handlers (RLV_TYPE_REPLY)
@ -202,13 +203,15 @@ protected:
std::stack<LLUUID> m_CurObjectStack; // Convenience (see @tpto)
rlv_behaviour_signal_t m_OnBehaviour;
rlv_behaviour_signal_t m_OnBehaviourToggle;
rlv_command_signal_t m_OnCommand;
mutable std::list<RlvCommandHandler*> m_CommandHandlers;
static BOOL m_fEnabled; // Use setEnabled() to toggle this
bool m_fCanCancelTp; // @accepttp and @tpto
mutable LLVector3d m_posSitSource; // @standtp (mutable because onForceXXX handles are all declared as const)
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
friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete
friend class RlvGCTimer; // Timer clear its own point at destruction
@ -230,12 +233,6 @@ extern rlv_handler_t gRlvHandler;
// Inlined member functions
//
// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
inline void RlvHandler::addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
{
m_Exceptions.insert(std::pair<ERlvBehaviour, RlvException>(eBhvr, RlvException(idObj, eBhvr, varOption)));
}
// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
inline bool RlvHandler::canEdit(const LLViewerObject* pObj) const
{
@ -280,31 +277,14 @@ inline bool RlvHandler::canShowHoverText(const LLViewerObject *pObj) const
(isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) );
}
// Checked: 2010-03-06 (RLVa-1.2.0c) | Added: RLVa-1.1.0j
inline bool RlvHandler::canSit(LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/) const
inline bool RlvHandler::canStartIM(const LLUUID& idRecipient) const
{
// The user can sit on the specified object if:
// - not prevented from sitting
// - not prevented from standing up or not currently sitting
// - not standtp restricted or not currently sitting (if the user is sitting and tried to sit elsewhere the tp would just kick in)
// - [regular sit] not @sittp=n or @fartouch=n restricted or if they clicked on a point within 1.5m of the avie's current position
// - [force sit] not @sittp=n restricted by a *different* object than the one that issued the command or the object is within 1.5m
return
( (pObj) && (LL_PCODE_VOLUME == pObj->getPCode()) ) &&
(!hasBehaviour(RLV_BHVR_SIT)) &&
( ((!hasBehaviour(RLV_BHVR_UNSIT)) && (!hasBehaviour(RLV_BHVR_STANDTP))) ||
((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting())) ) &&
( ((NULL == getCurrentCommand() || (RLV_BHVR_SIT != getCurrentCommand()->getBehaviourType()))
? ((!hasBehaviour(RLV_BHVR_SITTP)) && (!hasBehaviour(RLV_BHVR_FARTOUCH))) // [regular sit]
: (!hasBehaviourExcept(RLV_BHVR_SITTP, getCurrentObject()))) || // [force sit]
(dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < 1.5f * 1.5f) );
}
// Checked: 2010-03-07 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
inline bool RlvHandler::canStand() const
{
// NOTE: return FALSE only if we're @unsit=n restricted and the avie is currently sitting on something and TRUE for everything else
return (!hasBehaviour(RLV_BHVR_UNSIT)) || ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting()));
// User can start an IM session with "recipient" (could be an agent or a group) if:
// - not generally restricted from starting IM sessions (or the recipient is an exception)
// - not specifically restricted from starting an IM session with the recipient
return
( (!hasBehaviour(RLV_BHVR_STARTIM)) || (isException(RLV_BHVR_STARTIM, idRecipient)) ) &&
( (!hasBehaviour(RLV_BHVR_STARTIMTO)) || (!isException(RLV_BHVR_STARTIMTO, idRecipient)) );
}
// Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
@ -313,52 +293,14 @@ inline bool RlvHandler::canTeleportViaLure(const LLUUID& idAgent) const
return ((!hasBehaviour(RLV_BHVR_TPLURE)) || (isException(RLV_BHVR_TPLURE, idAgent))) && (canStand());
}
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const
{
return hasBehaviourExcept(eBehaviour, strOption, LLUUID::null);
return hasBehaviourExcept(eBhvr, strOption, LLUUID::null);
}
inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const
inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBhvr, const LLUUID& idObj) const
{
return hasBehaviourExcept(eBehaviour, std::string(), idObj);
}
// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
inline bool RlvHandler::hasException(ERlvBehaviour eBhvr) const
{
return (m_Exceptions.find(eBhvr) != m_Exceptions.end());
}
inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
{
return (RlvCommand::hasStrictVariant(eBhvr))
? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE)))
: true;
}
// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
inline void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
{
for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(eBhvr),
endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException)
{
if ( (itException->second.idObject == idObj) && (itException->second.varOption == varOption) )
{
m_Exceptions.erase(itException);
break;
}
}
}
// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
inline ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCommand, bool fFromObj)
{
if (STATE_STARTED != LLStartUp::getStartupState())
{
m_Retained.push_back(RlvCommand(idObj, strCommand));
return RLV_RET_RETAINED;
}
return processCommand(RlvCommand(idObj, strCommand), fFromObj);
return hasBehaviourExcept(eBhvr, LLStringUtil::null, idObj);
}
// ============================================================================

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,11 +15,11 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llattachmentsmgr.h"
#include "llgesturemgr.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
@ -29,6 +29,8 @@
#include "rlvhandler.h"
#include "rlvinventory.h"
#include <boost/algorithm/string.hpp>
// ============================================================================
// RlvCommmand
//
@ -37,7 +39,7 @@ RlvCommand::bhvr_map_t RlvCommand::m_BhvrMap;
// Checked: 2009-12-27 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
: m_idObj(idObj), m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN)
: m_fValid(false), m_idObj(idObj), m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN), m_eRet(RLV_RET_UNKNOWN)
{
if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam)))
{
@ -65,6 +67,9 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
return;
}
// HACK: all those @*overorreplace synonyms are rather tedious (and error-prone) to deal with so replace them their equivalent
if ( (RLV_TYPE_FORCE == m_eParamType) && (m_strBehaviour.length() - 13 == m_strBehaviour.rfind("overorreplace")) )
m_strBehaviour.erase(m_strBehaviour.length() - 13, 13);
// HACK: all those @addoutfit* synonyms are rather tedious (and error-prone) to deal with so replace them their @attach* equivalent
if ( (RLV_TYPE_FORCE == m_eParamType) && (0 == m_strBehaviour.find("addoutfit")) )
m_strBehaviour.replace(0, 9, "attach");
@ -149,18 +154,20 @@ void RlvCommand::initLookupTable()
// NOTE: keep this matched with the enumeration at all times
std::string arBehaviours[RLV_BHVR_COUNT] =
{
"detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "emote", "sendchat", "recvchat", "recvchatfrom",
"recvemote", "recvemotefrom", "redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel",
"sendim", "sendimto", "recvim", "recvimfrom", "permissive", "notify", "showinv", "showminimap", "showworldmap",
"showloc", "shownames", "showhovertext", "showhovertexthud", "showhovertextworld", "showhovertextall",
"tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture", "acceptpermission", "accepttp", "allowidle",
"displayname", "edit", "editobj", "rez", "fartouch", "interact", "touchobj", "touchattach", "touchattachself",
"touchattachother", "touchhud", "touchworld", "touchall", "fly", "unsit", "sit", "sittp", "standtp", "setdebug", "setenv",
"detachme", "attachover", "attachthis", "attachthisover", "detachthis", "attachall", "attachallover", "detachall",
"attachallthis", "attachallthisover", "detachallthis", "tpto", "version", "versionnew", "versionnum", "getattach",
"getattachnames", "getaddattachnames", "getremattachnames", "getoutfit", "getoutfitnames", "getaddoutfitnames",
"getremoutfitnames", "findfolder", "findfolders", "getpath", "getpathnew", "getinv", "getinvworn", "getsitid",
"getcommand", "getstatus", "getstatusall"
"detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "sharedwear", "sharedunwear",
"unsharedwear", "unsharedunwear", "emote", "sendchat", "recvchat", "recvchatfrom", "recvemote", "recvemotefrom",
"redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "sendimto",
"recvim", "recvimfrom", "startim", "startimto", "permissive", "notify", "showinv", "showminimap", "showworldmap", "showloc",
"shownames", "showhovertext", "showhovertexthud", "showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure",
"viewnote", "viewscript", "viewtexture", "acceptpermission", "accepttp", "allowidle", "edit", "editobj", "rez", "fartouch",
"interact", "touchthis", "touchattach", "touchattachself", "touchattachother", "touchhud", "touchworld", "touchall",
"touchme", "fly", "setgroup", "unsit", "sit", "sittp", "standtp", "setdebug", "setenv", "alwaysrun", "temprun", "detachme",
"attachover", "attachthis", "attachthisover", "attachthisexcept", "detachthis", "detachthisexcept", "attachall",
"attachallover", "detachall", "attachallthis", "attachallthisexcept", "attachallthisover", "detachallthis",
"detachallthisexcept", "adjustheight", "tpto", "version", "versionnew", "versionnum", "getattach", "getattachnames",
"getaddattachnames", "getremattachnames", "getoutfit", "getoutfitnames", "getaddoutfitnames", "getremoutfitnames",
"findfolder", "findfolders", "getpath", "getpathnew", "getinv", "getinvworn", "getgroup", "getsitid", "getcommand",
"getstatus", "getstatusall"
};
for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++)
@ -171,7 +178,7 @@ void RlvCommand::initLookupTable()
}
// ============================================================================
// RlvCommandOption
// RlvCommandOption structures
//
// Checked: 2010-09-28 (RLVa-1.2.1c) | Added: RLVa-1.2.1c
@ -195,14 +202,15 @@ RlvCommandOptionGeneric::RlvCommandOptionGeneric(const std::string& strOption)
else
m_varOption = strOption; // ... or it might just be a string
}
m_fValid = true;
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd)
: 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
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
{
@ -254,6 +262,36 @@ bool RlvCommandOptionGetPath::getItemIDs(LLWearableType::EType wtType, uuid_vec_
return (cntItemsPrev != idItems.size());
}
// Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
RlvCommandOptionAdjustHeight::RlvCommandOptionAdjustHeight(const RlvCommand& rlvCmd)
: m_nPelvisToFoot(0.0f), m_nPelvisToFootDeltaMult(0.0f), m_nPelvisToFootOffset(0.0f)
{
std::vector<std::string> cmdTokens;
boost::split(cmdTokens, rlvCmd.getOption(), boost::is_any_of(";"));
if (1 == cmdTokens.size())
{
m_fValid = (LLStringUtil::convertToF32(cmdTokens[0], m_nPelvisToFootOffset));
m_nPelvisToFootOffset = llclamp<F32>(m_nPelvisToFootOffset / 100, -1.0f, 1.0f);
}
else if ( (2 <= cmdTokens.size()) && (cmdTokens.size() <= 3) )
{
m_fValid = (LLStringUtil::convertToF32(cmdTokens[0], m_nPelvisToFoot)) &&
(LLStringUtil::convertToF32(cmdTokens[1], m_nPelvisToFootDeltaMult)) &&
( (2 == cmdTokens.size()) || (LLStringUtil::convertToF32(cmdTokens[2], m_nPelvisToFootOffset)) );
}
}
// Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
RlvCommandOptionTpTo::RlvCommandOptionTpTo(const RlvCommand &rlvCmd)
{
std::vector<std::string> cmdTokens;
boost::split(cmdTokens, rlvCmd.getOption(), boost::is_any_of("/"));
m_fValid = (3 == cmdTokens.size());
for (int idxAxis = 0; (idxAxis < 3) && (m_fValid); idxAxis++)
m_fValid &= (bool)LLStringUtil::convertToF64(cmdTokens[idxAxis], m_posGlobal[idxAxis]);
}
// =========================================================================
// RlvObject
//
@ -303,6 +341,19 @@ bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
return false; // Command was never added so nothing to remove now
}
// Checked: 2011-05-23 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
void RlvObject::setCommandRet(const RlvCommand& rlvCmd, ERlvCmdRet eRet)
{
for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
{
if (*itCmd == rlvCmd)
{
itCmd->m_eRet = eRet;
break;
}
}
}
bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const
{
for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
@ -953,18 +1004,53 @@ void RlvBehaviourNotifyHandler::onCommand(const RlvCommand& rlvCmd, ERlvCmdRet e
}
}
// Checked: 2010-09-23 (RLVa-1.2.1e) | Modified: RLVa-1.2.1e
void RlvBehaviourNotifyHandler::sendNotification(const std::string& strText, const std::string& strSuffix) const
// Checked: 2011-03-31 (RLVa-1.3.0f) | Modify: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::sendNotification(const std::string& strText, const std::string& strSuffix)
{
// NOTE: notifications have two parts (which are concatenated without token) where only the first part is subject to the filter
for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin();
itNotify != m_Notifications.end(); ++itNotify)
if (instanceExists())
{
if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strText.find(itNotify->second.strFilter)) )
RlvUtil::sendChatReply(itNotify->second.nChannel, "/" + strText + strSuffix);
RlvBehaviourNotifyHandler* pThis = getInstance();
// NOTE: notifications have two parts (which are concatenated without token) where only the first part is subject to the filter
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)) )
RlvUtil::sendChatReply(itNotify->second.nChannel, "/" + strText + strSuffix);
}
}
}
// Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::onWear(LLWearableType::EType eType, bool fAllowed)
{
sendNotification(llformat("worn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getTypeName(eType).c_str()));
}
// Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::onTakeOff(LLWearableType::EType eType, bool fAllowed)
{
sendNotification(llformat("unworn %s %s", (fAllowed) ? "legally" : "illegally", LLWearableType::getTypeName(eType).c_str()));
}
// Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::onAttach(const LLViewerJointAttachment* pAttachPt, bool fAllowed)
{
sendNotification(llformat("attached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str()));
}
// Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::onDetach(const LLViewerJointAttachment* pAttachPt, bool fAllowed)
{
sendNotification(llformat("detached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str()));
}
// Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
void RlvBehaviourNotifyHandler::onReattach(const LLViewerJointAttachment* pAttachPt, bool fAllowed)
{
sendNotification(llformat("reattached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str()));
}
// ============================================================================
// RlvWLSnapshot
//
@ -1014,32 +1100,6 @@ BOOL RlvGCTimer::tick()
// Various helper functions
//
// Checked: 2010-04-11 (RLVa-1.2.0b) | Modified: RLVa-0.2.0g
bool rlvCanDeleteOrReturn()
{
bool fIsAllowed = true;
if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ))
{
// We'll allow if none of the prims are owned by the avie or group owned
LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsOwnedByOrGroupOwned f(gAgent.getID());
if ( (handleSel.notNull()) && ((0 == handleSel->getRootObjectCount()) || (NULL != handleSel->getFirstRootNode(&f, FALSE))) )
fIsAllowed = false;
}
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (isAgentAvatarValid()) )
{
// We'll allow if the avie isn't sitting on any of the selected objects
LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsSittingOn f(gAgentAvatarp->getRoot());
if ( (handleSel.notNull()) && (handleSel->getFirstRootNode(&f, TRUE)) )
fIsAllowed = false;
}
return fIsAllowed;
}
// ============================================================================
// Attachment group helper functions
//
@ -1084,28 +1144,6 @@ ERlvAttachGroupType rlvAttachGroupFromString(const std::string& strGroup)
// String helper functions
//
// Checked: 2009-07-04 (RLVa-1.0.0a)
void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo)
{
if (strFrom.empty())
return;
size_t lenFrom = strFrom.length();
size_t lenTo = strTo.length();
std::string strTemp(strText);
LLStringUtil::toLower(strTemp);
LLStringUtil::toLower(strFrom);
std::string::size_type idxCur, idxStart = 0, idxOffset = 0;
while ( (idxCur = strTemp.find(strFrom, idxStart)) != std::string::npos)
{
strText.replace(idxCur + idxOffset, lenFrom, strTo);
idxStart = idxCur + lenFrom;
idxOffset += lenTo - lenFrom;
}
}
// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b
std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch /*=NULL*/)
{

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -18,20 +18,14 @@
#define RLV_HELPER_H
#include "lleventtimer.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
#include "llwearabletype.h"
#include "llwlparamset.h"
#include "rlvdefines.h"
#include "rlvcommon.h"
#ifdef LL_WINDOWS
#pragma warning (push)
#pragma warning (disable : 4702) // warning C4702: unreachable code
#endif
#include <boost/variant.hpp>
#ifdef LL_WINDOWS
#pragma warning (pop)
#endif
// ============================================================================
// RlvCommand
//
@ -52,6 +46,8 @@ public:
const std::string& getOption() const { return m_strOption; }
const std::string& getParam() const { return m_strParam; }
ERlvParamType getParamType() const { return m_eParamType; }
ERlvCmdRet getReturnType() const { return m_eRet; }
bool hasOption() const { return !m_strOption.empty(); }
bool isStrict() const { return m_fStrict; }
bool isValid() const { return m_fValid; }
@ -83,98 +79,92 @@ protected:
std::string m_strOption;
std::string m_strParam;
ERlvParamType m_eParamType;
ERlvCmdRet m_eRet;
static bhvr_map_t m_BhvrMap;
friend class RlvHandler;
friend class RlvObject;
};
typedef std::list<RlvCommand> rlv_command_list_t;
// ============================================================================
// RlvCommandOption (and derived classed)
//
class RlvCommandOption
struct RlvCommandOption
{
protected:
RlvCommandOption() {}
RlvCommandOption() : m_fValid(false) {}
public:
virtual ~RlvCommandOption() {}
public:
virtual bool isAttachmentPoint() const { return false; }
virtual bool isAttachmentPointGroup() const { return false; }
virtual bool isEmpty() const = 0;
virtual bool isSharedFolder() const { return false; }
virtual bool isString() const { return false; }
virtual bool isUUID() const { return false; }
virtual bool isValid() const = 0;
virtual bool isWearableType() const { return false; }
virtual LLViewerJointAttachment* getAttachmentPoint() const { return NULL; }
virtual ERlvAttachGroupType getAttachmentPointGroup() const { return RLV_ATTACHGROUP_INVALID; }
virtual LLViewerInventoryCategory* getSharedFolder() const { return NULL; }
virtual const std::string& getString() const { return LLStringUtil::null; }
virtual const LLUUID& getUUID() const { return LLUUID::null; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_INVALID; }
virtual bool isEmpty() const { return false; }
virtual bool isValid() const { return m_fValid; }
protected:
bool m_fValid;
};
class RlvCommandOptionGeneric : public RlvCommandOption
struct RlvCommandOptionGeneric : public RlvCommandOption
{
public:
explicit RlvCommandOptionGeneric(const std::string& strOption);
RlvCommandOptionGeneric(LLViewerJointAttachment* pAttachPt) : m_fEmpty(false) { m_varOption = pAttachPt; }
RlvCommandOptionGeneric(LLViewerInventoryCategory* pFolder) : m_fEmpty(false) { m_varOption = pFolder; }
RlvCommandOptionGeneric(const LLUUID& idOption) : m_fEmpty(false) { m_varOption = idOption; }
RlvCommandOptionGeneric(LLWearableType::EType wtType) : m_fEmpty(false) { m_varOption = wtType; }
/*virtual*/ ~RlvCommandOptionGeneric() {}
public:
/*virtual*/ bool isAttachmentPoint() const { return (!isEmpty()) && (typeid(LLViewerJointAttachment*) == m_varOption.type()); }
/*virtual*/ bool isAttachmentPointGroup() const { return (!isEmpty()) && (typeid(ERlvAttachGroupType) == m_varOption.type()); }
/*virtual*/ bool isEmpty() const { return m_fEmpty; }
/*virtual*/ bool isSharedFolder() const { return (!isEmpty()) && (typeid(LLViewerInventoryCategory*) == m_varOption.type()); }
/*virtual*/ bool isString() const { return (!isEmpty()) && (typeid(std::string) == m_varOption.type()); }
/*virtual*/ bool isUUID() const { return (!isEmpty()) && (typeid(LLUUID) == m_varOption.type()); }
/*virtual*/ bool isValid() const { return true; } // This doesn't really have any significance for the generic class
/*virtual*/ bool isWearableType() const { return (!isEmpty()) && (typeid(LLWearableType::EType) == m_varOption.type()); }
bool isAttachmentPoint() const { return (!isEmpty()) && (typeid(LLViewerJointAttachment*) == m_varOption.type()); }
bool isAttachmentPointGroup() const { return (!isEmpty()) && (typeid(ERlvAttachGroupType) == m_varOption.type()); }
bool isEmpty() const { return m_fEmpty; }
bool isSharedFolder() const { return (!isEmpty()) && (typeid(LLViewerInventoryCategory*) == m_varOption.type()); }
bool isString() const { return (!isEmpty()) && (typeid(std::string) == m_varOption.type()); }
bool isUUID() const { return (!isEmpty()) && (typeid(LLUUID) == m_varOption.type()); }
bool isWearableType() const { return (!isEmpty()) && (typeid(LLWearableType::EType) == m_varOption.type()); }
/*virtual*/ LLViewerJointAttachment* getAttachmentPoint() const
{ return (isAttachmentPoint()) ? boost::get<LLViewerJointAttachment*>(m_varOption) : RlvCommandOption::getAttachmentPoint(); }
/*virtual*/ ERlvAttachGroupType getAttachmentPointGroup() const
{ return (isAttachmentPointGroup()) ? boost::get<ERlvAttachGroupType>(m_varOption) : RlvCommandOption::getAttachmentPointGroup(); }
/*virtual*/ LLViewerInventoryCategory* getSharedFolder() const
{ return (isSharedFolder()) ? boost::get<LLViewerInventoryCategory*>(m_varOption) : RlvCommandOption::getSharedFolder(); }
/*virtual*/ const std::string& getString() const
{ return (isString()) ? boost::get<std::string>(m_varOption) : RlvCommandOption::getString(); }
/*virtual*/ const LLUUID& getUUID() const
{ return (isUUID()) ? boost::get<LLUUID>(m_varOption) : RlvCommandOption::getUUID(); }
/*virtual*/ LLWearableType::EType getWearableType() const
{ return (isWearableType()) ? boost::get<LLWearableType::EType>(m_varOption) : RlvCommandOption::getWearableType(); }
LLViewerJointAttachment* getAttachmentPoint() const
{ return (isAttachmentPoint()) ? boost::get<LLViewerJointAttachment*>(m_varOption) : NULL; }
ERlvAttachGroupType getAttachmentPointGroup() const
{ return (isAttachmentPointGroup()) ? boost::get<ERlvAttachGroupType>(m_varOption) : RLV_ATTACHGROUP_INVALID; }
LLViewerInventoryCategory* getSharedFolder() const
{ return (isSharedFolder()) ? boost::get<LLViewerInventoryCategory*>(m_varOption) : NULL; }
const std::string& getString() const
{ return (isString()) ? boost::get<std::string>(m_varOption) : LLStringUtil::null; }
const LLUUID& getUUID() const
{ return (isUUID()) ? boost::get<LLUUID>(m_varOption) : LLUUID::null; }
LLWearableType::EType getWearableType() const
{ return (isWearableType()) ? boost::get<LLWearableType::EType>(m_varOption) : LLWearableType::WT_INVALID; }
protected:
bool m_fEmpty;
boost::variant<LLViewerJointAttachment*, ERlvAttachGroupType, LLViewerInventoryCategory*, std::string, LLUUID, LLWearableType::EType> m_varOption;
};
class RlvCommandOptionGetPath : public RlvCommandOption
struct RlvCommandOptionGetPath : public RlvCommandOption
{
public:
RlvCommandOptionGetPath(const RlvCommand& rlvCmd);
/*virtual*/ ~RlvCommandOptionGetPath() {}
/*virtual*/ bool isEmpty() const { return m_idItems.empty(); }
/*virtual*/ bool isValid() const { return m_fValid; }
const uuid_vec_t& getItemIDs() const { return m_idItems; }
static bool getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems, bool fClear = true);
static bool getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear = true);
protected:
bool m_fValid;
uuid_vec_t m_idItems;
};
struct RlvCommandOptionAdjustHeight : public RlvCommandOption
{
RlvCommandOptionAdjustHeight(const RlvCommand& rlvCmd);
F32 m_nPelvisToFoot;
F32 m_nPelvisToFootDeltaMult;
F32 m_nPelvisToFootOffset;
};
struct RlvCommandOptionTpTo : public RlvCommandOption
{
RlvCommandOptionTpTo(const RlvCommand& rlvCmd);
LLVector3d m_posGlobal;
};
// ============================================================================
// RlvObject
//
@ -190,6 +180,7 @@ public:
public:
bool addCommand(const RlvCommand& rlvCmd);
bool removeCommand(const RlvCommand& rlvCmd);
void setCommandRet(const RlvCommand& rlvCmd, ERlvCmdRet eRet);
std::string getStatusString(const std::string& strMatch) const;
bool hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const;
@ -198,6 +189,7 @@ public:
const rlv_command_list_t* getCommandList() const { return &m_Commands; }
const LLUUID& getObjectID() const { return m_idObj; }
const LLUUID& getRootID() const { return m_idRoot; }
/*
* Member variables
@ -335,9 +327,19 @@ public:
if (m_Notifications.empty())
delete this; // Delete ourself if we have nothing to do
}
void sendNotification(const std::string& strText, const std::string& strSuffix = LLStringUtil::null) const;
static void sendNotification(const std::string& strText, const std::string& strSuffix = LLStringUtil::null);
/*
* Event handlers
*/
public:
static void onWear(LLWearableType::EType eType, bool fAllowed);
static void onTakeOff(LLWearableType::EType eType, bool fAllowed);
static void onAttach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
static void onDetach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
static void onReattach(const LLViewerJointAttachment* pAttachPt, bool fAllowed);
protected:
void onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet, bool fInternal);
void onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet, bool fInternal);
protected:
struct notifyData
@ -354,8 +356,6 @@ protected:
// RlvException
//
typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
struct RlvException
{
public:
@ -372,7 +372,7 @@ private:
// RlvWLSnapshot
//
struct RlvWLSnapshot
class RlvWLSnapshot
{
public:
static void restoreSnapshot(const RlvWLSnapshot* pWLSnapshot);
@ -421,14 +421,11 @@ inline void rlvCallbackTimerOnce(F32 nPeriod, RlvCallbackTimerOnce::nullary_func
// Various helper functions
//
bool rlvCanDeleteOrReturn();
ERlvAttachGroupType rlvAttachGroupFromIndex(S32 idxGroup);
ERlvAttachGroupType rlvAttachGroupFromString(const std::string& strGroup);
std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL);
std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL);
void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo);
// ============================================================================
// Inlined class member functions

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -63,6 +63,35 @@ public:
// RlvInventory member functions
//
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
RlvInventory::RlvInventory()
: m_fFetchStarted(false), m_fFetchComplete(false)
{
}
// Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
RlvInventory::~RlvInventory()
{
if (gInventory.containsObserver(this))
gInventory.removeObserver(this);
}
// Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
void RlvInventory::changed(U32 mask)
{
const LLInventoryModel::changed_items_t& idsChanged = gInventory.getChangedIDs();
if (std::find(idsChanged.begin(), idsChanged.end(), m_idRlvRoot) != idsChanged.end())
{
gInventory.removeObserver(this);
LLUUID idRlvRootPrev = m_idRlvRoot;
m_idRlvRoot.setNull();
if (idRlvRootPrev != getSharedRootID())
m_OnSharedRootIDChanged();
}
}
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h
void RlvInventory::fetchSharedInventory()
{
@ -213,25 +242,29 @@ bool RlvInventory::getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_arra
return (folders.count() != 0);
}
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h
LLViewerInventoryCategory* RlvInventory::getSharedRoot() const
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
const LLUUID& RlvInventory::getSharedRootID() const
{
if (gInventory.isInventoryUsable())
if ( (m_idRlvRoot.isNull()) && (gInventory.isInventoryUsable()) )
{
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), pFolders, pItems);
if (pFolders)
{
// NOTE: we might have multiple #RLV folders so we'll just go with the first one we come across
LLViewerInventoryCategory* pFolder;
const LLViewerInventoryCategory* pFolder;
for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
{
if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (RlvInventory::cstrSharedRoot == pFolder->getName()) )
return pFolder;
if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (cstrSharedRoot == pFolder->getName()) )
{
if (!gInventory.containsObserver((RlvInventory*)this))
gInventory.addObserver((RlvInventory*)this);
m_idRlvRoot = pFolder->getUUID();
}
}
}
}
return NULL;
return m_idRlvRoot;
}
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.1a
@ -497,7 +530,7 @@ void RlvGiveToRLVTaskOffer::doneIdle()
pNewFolder->updateServer(FALSE);
gInventory.updateCategory(pNewFolder);
RlvBehaviourNotifyHandler::instance().sendNotification("accepted_in_rlv inv_offer " + pNewFolder->getName());
RlvBehaviourNotifyHandler::sendNotification("accepted_in_rlv inv_offer " + pNewFolder->getName());
gInventory.notifyObservers();
break;

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -29,30 +29,37 @@
// RlvInventory class declaration
//
// TODO-RLVa: [RLVa-1.2.0] Make all of this static rather than a singleton?
class RlvInventory : public LLSingleton<RlvInventory>
class RlvInventory : public LLSingleton<RlvInventory>, public LLInventoryObserver
{
protected:
RlvInventory() : m_fFetchStarted(false), m_fFetchComplete(false) {}
RlvInventory();
public:
~RlvInventory();
// LLInventoryObserver override
/*virtual*/ void changed(U32 mask);
/*
* #RLV Shared inventory
*/
public:
typedef boost::signals2::signal<void (void)> callback_signal_t;
void addSharedRootIDChangedCallback(const callback_signal_t::slot_type& cb) { m_OnSharedRootIDChanged.connect(cb); }
// Find all folders that match a supplied criteria (clears the output array)
bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const;
bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const;
// Gets the shared path for any shared items present in idItems (clears the output array)
bool getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_array_t& folders) const;
bool getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_array_t& folders) const;
// Returns a pointer to the shared root folder (if there is one)
LLViewerInventoryCategory* getSharedRoot() const;
LLViewerInventoryCategory* getSharedRoot() const;
const LLUUID& getSharedRootID() const;
// Returns a subfolder of idParent that starts with strFolderName (exact match > partial match)
LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const;
LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const;
// Looks up a folder from a path (relative to the shared root)
LLViewerInventoryCategory* getSharedFolder(const std::string& strPath) const;
LLViewerInventoryCategory* getSharedFolder(const std::string& strPath) const;
// Returns the path of the supplied folder (relative to the shared root)
std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const;
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);
bool isSharedFolder(const LLUUID& idFolder);
/*
* Inventory fetching
@ -76,8 +83,10 @@ public:
* Member variables
*/
protected:
bool m_fFetchStarted; // TRUE if we fired off an inventory fetch
bool m_fFetchComplete; // TRUE if everything was fetched
bool m_fFetchStarted; // TRUE if we fired off an inventory fetch
bool m_fFetchComplete; // TRUE if everything was fetched
mutable LLUUID m_idRlvRoot;
callback_signal_t m_OnSharedRootIDChanged;
private:
static const std::string cstrSharedRoot;
@ -227,6 +236,13 @@ public:
// RlvInventory inlined member functions
//
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
inline LLViewerInventoryCategory* RlvInventory::getSharedRoot() const
{
const LLUUID& idRlvRoot = getSharedRootID();
return (idRlvRoot.notNull()) ? gInventory.getCategory(idRlvRoot) : NULL;
}
// Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
inline bool RlvInventory::isFoldedFolder(const LLInventoryCategory* pFolder, bool fCheckComposite)
{

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,15 +15,17 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llappearancemgr.h"
#include "llattachmentsmgr.h"
#include "llinventoryobserver.h"
#include "lloutfitobserver.h"
#include "llviewerobjectlist.h"
#include "pipeline.h"
#include "rlvlocks.h"
#include "rlvhelper.h"
#include "rlvinventory.h"
#include "rlvlocks.h"
// ============================================================================
// RlvAttachPtLookup member functions
@ -203,6 +205,21 @@ void RlvAttachmentLocks::addAttachmentPointLock(S32 idxAttachPt, const LLUUID& i
m_AttachPtAdd.insert(std::pair<S32, LLUUID>(idxAttachPt, idRlvObj));
}
// Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b
bool RlvAttachmentLocks::canAttach() const
{
if (isAgentAvatarValid())
{
for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = gAgentAvatarp->mAttachmentPoints.begin();
itAttachPt != gAgentAvatarp->mAttachmentPoints.end(); ++itAttachPt)
{
if (!isLockedAttachmentPoint(itAttachPt->first, RLV_LOCK_ADD))
return true;
}
}
return false;
}
// Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
bool RlvAttachmentLocks::canDetach(const LLViewerJointAttachment* pAttachPt, bool fDetachAll /*=false*/) const
{
@ -510,7 +527,7 @@ void RlvAttachmentLockWatchdog::detach(S32 idxAttachPt, const LLViewerObject* pA
if (!pAttachPt)
return;
c_llvo_vec_t attachObjs;
std::vector<const LLViewerObject*> attachObjs;
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
{
@ -526,7 +543,7 @@ void RlvAttachmentLockWatchdog::detach(S32 idxAttachPt, const LLViewerObject* pA
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
for (c_llvo_vec_t::const_iterator itAttachObj = attachObjs.begin(); itAttachObj != attachObjs.end(); ++itAttachObj)
for (std::vector<const LLViewerObject*>::const_iterator itAttachObj = attachObjs.begin(); itAttachObj != attachObjs.end(); ++itAttachObj)
{
const LLViewerObject* pAttachObj = *itAttachObj;
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
@ -574,17 +591,21 @@ void RlvAttachmentLockWatchdog::onAttach(const LLViewerObject* pAttachObj, const
if (idAttachItem == itAttach->second.idItem)
{
fPendingReattach = true;
RlvBehaviourNotifyHandler::onReattach(pAttachPt, true);
m_PendingAttach.erase(itAttach);
break;
}
}
if (!fPendingReattach)
{
detach(pAttachObj);
RlvBehaviourNotifyHandler::onAttach(pAttachPt, false);
}
return;
}
// Check if the attach was allowed at the time it was requested
rlv_wear_map_t::iterator itWear = m_PendingWear.find(idAttachItem);
rlv_wear_map_t::iterator itWear = m_PendingWear.find(idAttachItem); bool fAttachAllowed = true;
if (itWear != m_PendingWear.end())
{
// We'll need to return the attachment point to its previous state if it was non-attachable
@ -603,7 +624,6 @@ void RlvAttachmentLockWatchdog::onAttach(const LLViewerObject* pAttachObj, const
else
{
// Iterate over all the current attachments and force detach any that shouldn't be there
c_llvo_vec_t attachObjs;
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
{
@ -624,26 +644,27 @@ void RlvAttachmentLockWatchdog::onAttach(const LLViewerObject* pAttachObj, const
m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(*itAttach)));
}
}
fAttachAllowed = false;
}
}
else if (RLV_WEAR_REPLACE == itWear->second.eWearAction)
{
// Now that we know where this attaches to check if we can actually perform a "replace"
bool fCanReplace = true;
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
((itAttachObj != pAttachPt->mAttachedObjects.end()) && (fCanReplace)); ++itAttachObj)
((itAttachObj != pAttachPt->mAttachedObjects.end()) && (fAttachAllowed)); ++itAttachObj)
{
if (pAttachObj != *itAttachObj)
fCanReplace &= !gRlvAttachmentLocks.isLockedAttachment(*itAttachObj);
fAttachAllowed &= !gRlvAttachmentLocks.isLockedAttachment(*itAttachObj);
}
if (fCanReplace)
if (fAttachAllowed)
detach(idxAttachPt, pAttachObj); // Replace == allowed: detach everything except the new attachment
else
detach(pAttachObj); // Replace != allowed: detach the new attachment
}
m_PendingWear.erase(itWear); // No need to start the timer since it should be running already if '!m_PendingWear.empty()'
}
RlvBehaviourNotifyHandler::onAttach(pAttachPt, fAttachAllowed);
}
// Checked: 2010-07-28 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
@ -660,10 +681,12 @@ void RlvAttachmentLockWatchdog::onDetach(const LLViewerObject* pAttachObj, const
if (itDetach != m_PendingDetach.end())
{
m_PendingDetach.erase(itDetach);
RlvBehaviourNotifyHandler::onDetach(pAttachPt, true);
return;
}
// If the attachment is currently "remove locked" then we should reattach it (unless it's already pending reattach)
bool fDetachAllowed = true;
if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj))
{
bool fPendingAttach = false;
@ -684,7 +707,9 @@ void RlvAttachmentLockWatchdog::onDetach(const LLViewerObject* pAttachObj, const
m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(idAttachItem)));
startTimer();
}
fDetachAllowed = false;
}
RlvBehaviourNotifyHandler::onDetach(pAttachPt, fDetachAllowed);
}
// Checked: 2010-03-05 (RLVa-1.2.0a) | Modified: RLVa-1.0.5b
@ -916,236 +941,324 @@ void RlvWearableLocks::removeWearableTypeLock(LLWearableType::EType eType, const
// RlvFolderLocks member functions
//
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
class RlvLockedDescendentsCollector : public LLInventoryCollectFunctor
{
public:
RlvLockedDescendentsCollector(int eSourceTypeMask, RlvFolderLocks::ELockPermission ePermMask, ERlvLockMask eLockTypeMask)
: m_eSourceTypeMask(eSourceTypeMask), m_ePermMask(ePermMask), m_eLockTypeMask(eLockTypeMask) {}
/*virtual*/ ~RlvLockedDescendentsCollector() {}
/*virtual*/ bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem)
{
return (pFolder) && (RlvFolderLocks::instance().isLockedFolderEntry(pFolder->getUUID(), m_eSourceTypeMask, m_ePermMask, m_eLockTypeMask));
}
protected:
RlvFolderLocks::ELockPermission m_ePermMask;
int m_eSourceTypeMask;
ERlvLockMask m_eLockTypeMask;
};
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
RlvFolderLocks::RlvFolderLocks()
: m_fItemsDirty(true)
: m_fLookupDirty(false), m_fLockedRoot(false)
{
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onCOFChanged, this));
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
RlvInventory::instance().addSharedRootIDChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::addFolderLock(const rlv_folderlock_descr_t& lockDescr, const LLUUID& idRlvObj, ERlvLockMask eLock)
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
void RlvFolderLocks::addFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope,
const LLUUID& idRlvObj, ERlvLockMask eLockType)
{
/*
// Sanity check - make sure it's an object we know about
if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) )
return; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE)
*/
// Sanity check - eLockType can be RLV_LOCK_ADD or RLV_LOCK_REMOVE but not both
RLV_ASSERT( (RLV_LOCK_ADD == eLockType) || (RLV_LOCK_REMOVE == eLockType) );
// NOTE: m_FolderXXX can contain duplicate <idRlvObj, lockDescr> pairs
if (eLock & RLV_LOCK_REMOVE)
m_FolderRem.insert(std::pair<LLUUID, rlv_folderlock_descr_t>(idRlvObj, lockDescr));
if (eLock & RLV_LOCK_ADD)
m_FolderAdd.insert(std::pair<LLUUID, rlv_folderlock_descr_t>(idRlvObj, lockDescr));
// NOTE: m_FolderXXX can contain duplicate folderlock_descr_t
m_FolderLocks.push_back(new folderlock_descr_t(idRlvObj, eLockType, lockSource, ePerm, eScope));
m_fItemsDirty = true;
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::removeFolderLock(const rlv_folderlock_descr_t& lockDescr, const LLUUID& idRlvObj, ERlvLockMask eLock)
{
/*
// Sanity check - make sure it's an object we know about
if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) )
return; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE)
*/
if (eLock & RLV_LOCK_REMOVE)
if (PERM_DENY == ePerm)
{
RLV_ASSERT( m_FolderRem.lower_bound(idRlvObj) != m_FolderRem.upper_bound(idRlvObj) ); // The lock should always exist
for (rlv_folderlock_map_t::iterator itFolderLock = m_FolderRem.lower_bound(idRlvObj),
endFolderLock = m_FolderRem.upper_bound(idRlvObj); itFolderLock != endFolderLock; ++itFolderLock)
{
if (lockDescr == itFolderLock->second)
if (RLV_LOCK_REMOVE == eLockType)
m_cntLockRem++;
else if (RLV_LOCK_ADD == eLockType)
m_cntLockAdd++;
}
m_fLookupDirty = true;
}
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
bool RlvFolderLocks::getLockedFolders(const folderlock_source_t& lockSource, LLInventoryModel::cat_array_t& lockFolders) const
{
S32 cntFolders = lockFolders.count();
switch (lockSource.first)
{
case ST_ATTACHMENT:
{
m_FolderRem.erase(itFolderLock);
break;
}
}
}
if (eLock & RLV_LOCK_ADD)
{
RLV_ASSERT( m_FolderAdd.lower_bound(idRlvObj) != m_FolderAdd.upper_bound(idRlvObj) ); // The lock should always exist
for (rlv_folderlock_map_t::iterator itFolderLock = m_FolderAdd.lower_bound(idRlvObj),
endFolderLock = m_FolderAdd.upper_bound(idRlvObj); itFolderLock != endFolderLock; ++endFolderLock)
{
if (lockDescr == itFolderLock->second)
{
m_FolderAdd.erase(itFolderLock);
break;
}
}
}
m_fItemsDirty = true;
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::getLockedFolders(const rlv_folderlock_descr_t& lockDescr, LLInventoryModel::cat_array_t& lockFolders) const
{
if (typeid(LLUUID) == lockDescr.first.type()) // Folder lock by attachment UUID
{
const LLViewerObject* pObj = gObjectList.findObject(boost::get<LLUUID>(lockDescr.first));
if ( (pObj) && (pObj->isAttachment()) )
{
const LLViewerInventoryItem* pItem = gInventory.getItem(pObj->getAttachmentItemID());
if ( (pItem) && (RlvInventory::instance().isSharedFolder(pItem->getParentUUID())) )
{
LLViewerInventoryCategory* pParentFolder = gInventory.getCategory(pItem->getParentUUID());
if (pParentFolder)
lockFolders.push_back(pParentFolder);
}
}
}
else if (typeid(std::string) == lockDescr.first.type()) // Folder lock by shared path
{
LLViewerInventoryCategory* pSharedFolder = RlvInventory::instance().getSharedFolder(boost::get<std::string>(lockDescr.first));
if (pSharedFolder)
lockFolders.push_back(pSharedFolder);
}
else // Folder lock by attachment point or wearable type
{
uuid_vec_t idItems;
if (typeid(S32) == lockDescr.first.type())
RlvCommandOptionGetPath::getItemIDs(RlvAttachPtLookup::getAttachPoint(boost::get<S32>(lockDescr.first)), idItems);
else if (typeid(LLWearableType::EType) == lockDescr.first.type())
RlvCommandOptionGetPath::getItemIDs(boost::get<LLWearableType::EType>(lockDescr.first), idItems);
LLInventoryModel::cat_array_t folders;
if (RlvInventory::instance().getPath(idItems, folders))
lockFolders.insert(lockFolders.end(), folders.begin(), folders.end());
}
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
bool RlvFolderLocks::getLockedFolders(ERlvLockMask eLock, LLInventoryModel::cat_array_t& nodeFolders, LLInventoryModel::cat_array_t& subtreeFolders) const
{
nodeFolders.clear();
subtreeFolders.clear();
// Bit of a hack, but the code is identical for both
const rlv_folderlock_map_t* pLockMaps[2] = { 0 };
if (eLock & RLV_LOCK_REMOVE)
pLockMaps[0] = &m_FolderRem;
if (eLock & RLV_LOCK_ADD)
pLockMaps[1] = &m_FolderAdd;
for (int idxLockMap = 0, cntLockMap = sizeof(pLockMaps) / sizeof(rlv_folderlock_map_t*); idxLockMap < cntLockMap; idxLockMap++)
{
if (!pLockMaps[idxLockMap])
continue;
// Iterate over each folder lock and determine which folders it affects
for (rlv_folderlock_map_t::const_iterator itFolderLock = pLockMaps[idxLockMap]->begin(), endFolderLock = pLockMaps[idxLockMap]->end();
itFolderLock != endFolderLock; ++itFolderLock)
{
const rlv_folderlock_descr_t& lockDescr = itFolderLock->second;
getLockedFolders(lockDescr, (!lockDescr.second) ? nodeFolders : subtreeFolders);
}
}
// Remove any duplicates we may have picked up
bool fEmpty = (nodeFolders.empty()) && (subtreeFolders.empty());
if (!fEmpty)
{
std::sort(nodeFolders.begin(), nodeFolders.end());
nodeFolders.erase(std::unique(nodeFolders.begin(), nodeFolders.end()), nodeFolders.end());
std::sort(subtreeFolders.begin(), subtreeFolders.end());
subtreeFolders.erase(std::unique(subtreeFolders.begin(), subtreeFolders.end()), subtreeFolders.end());
}
return !fEmpty;
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::refreshLockedItems(ERlvLockMask eLock, LLInventoryModel::cat_array_t lockFolders, bool fMatchAll) const
{
// Sanity check - eLock can be RLV_LOCK_REMOVE or RLV_LOCK_ADD but not both
uuid_vec_t* pLockedFolders = (RLV_LOCK_REMOVE == eLock) ? &m_LockedFolderRem : ((RLV_LOCK_ADD == eLock) ? &m_LockedFolderAdd : NULL);
if (!pLockedFolders)
return;
// Mimick an @attach:<folder>=force for each folder lock and keep track of every folder that has an item that would get worn
for (S32 idxFolder = 0, cntFolder = lockFolders.count(); idxFolder < cntFolder; idxFolder++)
{
const LLViewerInventoryCategory* pFolder = lockFolders.get(idxFolder);
// Grab a list of all the items we would be wearing/attaching
LLInventoryModel::cat_array_t foldersAttach; LLInventoryModel::item_array_t itemsAttach;
RlvWearableItemCollector f(pFolder, RlvForceWear::ACTION_WEAR_REPLACE,
(fMatchAll) ? RlvForceWear::FLAG_MATCHALL : RlvForceWear::FLAG_NONE);
gInventory.collectDescendentsIf(pFolder->getUUID(), foldersAttach, itemsAttach, FALSE, f, TRUE);
for (S32 idxItem = 0, cntItem = itemsAttach.count(); idxItem < cntItem; idxItem++)
{
const LLViewerInventoryItem* pItem = itemsAttach.get(idxItem);
if ( (!pItem) || ((RLV_LOCK_REMOVE != eLock) || (!RlvForceWear::isWearingItem(pItem))) )
continue;
// NOTE: this won't keep track of every folder we need to (i.e. some may not have any wearable items) but our move/delete logic
// will take care of any we miss here
pLockedFolders->push_back(pItem->getParentUUID());
// Only keep track of items when it's a RLV_LOCK_REMOVE folder lock
if (RLV_LOCK_REMOVE == eLock)
{
switch (pItem->getType())
RLV_ASSERT(typeid(LLUUID) == lockSource.second.type())
const LLViewerObject* pObj = gObjectList.findObject(boost::get<LLUUID>(lockSource.second));
if ( (pObj) && (pObj->isAttachment()) )
{
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
m_LockedWearableRem.push_back(pItem->getLinkedUUID());
break;
case LLAssetType::AT_OBJECT:
m_LockedAttachmentRem.push_back(pItem->getLinkedUUID());
break;
default:
break;
const LLViewerInventoryItem* pItem = gInventory.getItem(pObj->getAttachmentItemID());
if ( (pItem) && (RlvInventory::instance().isSharedFolder(pItem->getParentUUID())) )
{
LLViewerInventoryCategory* pItemFolder = gInventory.getCategory(pItem->getParentUUID());
if (pItemFolder)
lockFolders.push_back(pItemFolder);
}
}
}
}
}
break;
case ST_FOLDER:
{
RLV_ASSERT(typeid(LLUUID) == lockSource.second.type())
LLViewerInventoryCategory* pFolder = gInventory.getCategory(boost::get<LLUUID>(lockSource.second));
if (pFolder)
lockFolders.push_back(pFolder);
}
break;
case ST_ROOTFOLDER:
{
LLViewerInventoryCategory* pFolder = gInventory.getCategory(gInventory.getRootFolderID());
if (pFolder)
lockFolders.push_back(pFolder);
}
break;
case ST_SHAREDPATH:
{
RLV_ASSERT(typeid(std::string) == lockSource.second.type())
LLViewerInventoryCategory* pSharedFolder = RlvInventory::instance().getSharedFolder(boost::get<std::string>(lockSource.second));
if (pSharedFolder)
lockFolders.push_back(pSharedFolder);
}
break;
case ST_ATTACHMENTPOINT:
case ST_WEARABLETYPE:
{
RLV_ASSERT( ((ST_ATTACHMENTPOINT == lockSource.first) && (typeid(S32) == lockSource.second.type())) ||
((ST_WEARABLETYPE == lockSource.first) && (typeid(LLWearableType::EType) == lockSource.second.type())) );
uuid_vec_t idItems;
if (ST_ATTACHMENTPOINT == lockSource.first)
RlvCommandOptionGetPath::getItemIDs(RlvAttachPtLookup::getAttachPoint(boost::get<S32>(lockSource.second)), idItems);
else if (ST_WEARABLETYPE == lockSource.first)
RlvCommandOptionGetPath::getItemIDs(boost::get<LLWearableType::EType>(lockSource.second), idItems);
LLInventoryModel::cat_array_t itemFolders;
if (RlvInventory::instance().getPath(idItems, itemFolders))
lockFolders.insert(lockFolders.end(), itemFolders.begin(), itemFolders.end());
}
break;
default:
return false;
};
return cntFolders != lockFolders.count();
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::refreshLockedItems() const
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
bool RlvFolderLocks::getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const
{
if (m_fItemsDirty)
S32 cntItems = lockItems.count();
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
LLFindWearablesEx f(true, true); // Collect all worn wearables and body parts
gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f);
LLUUID idPrev; bool fPrevLocked = false;
for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
{
// Clear any previously cached items or folders
m_fItemsDirty = false;
m_LockedFolderAdd.clear();
m_LockedAttachmentRem.clear();
m_LockedFolderRem.clear();
m_LockedWearableRem.clear();
LLInventoryModel::cat_array_t nodeFolders, subtreeFolders;
if (getLockedFolders(RLV_LOCK_REMOVE, nodeFolders, subtreeFolders))
LLViewerInventoryItem* pItem = items.get(idxItem);
if ( (fFollowLinks) && (LLAssetType::AT_LINK == pItem->getActualType()) )
pItem = pItem->getLinkedItem();
if (!pItem)
continue;
if (pItem->getParentUUID() != idPrev)
{
// Process node and subtree folder locks
refreshLockedItems(RLV_LOCK_REMOVE, nodeFolders, false); // @detachthis[:<option>]=n
refreshLockedItems(RLV_LOCK_REMOVE, subtreeFolders, true); // @detachallthis[:<option>]=n
// Remove any duplicates we may have picked up
std::sort(m_LockedFolderRem.begin(), m_LockedFolderRem.end());
m_LockedFolderRem.erase(std::unique(m_LockedFolderRem.begin(), m_LockedFolderRem.end()), m_LockedFolderRem.end());
idPrev = pItem->getParentUUID();
fPrevLocked = isLockedFolder(idPrev, RLV_LOCK_REMOVE);
}
if (getLockedFolders(RLV_LOCK_ADD, nodeFolders, subtreeFolders))
{
// Process node and subtree folder locks
refreshLockedItems(RLV_LOCK_ADD, nodeFolders, false); // @attachthis[:<option>]=n
refreshLockedItems(RLV_LOCK_ADD, subtreeFolders, true); // @attachallthis[:<option>]=n
if (fPrevLocked)
lockItems.push_back(pItem);
}
// Remove any duplicates we may have picked up
std::sort(m_LockedFolderAdd.begin(), m_LockedFolderAdd.end());
m_LockedFolderAdd.erase(std::unique(m_LockedFolderAdd.begin(), m_LockedFolderAdd.end()), m_LockedFolderAdd.end());
return cntItems != lockItems.count();
}
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
bool RlvFolderLocks::hasLockedFolderDescendent(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask,
ERlvLockMask eLockTypeMask, bool fCheckSelf) const
{
if (!hasLockedFolder(eLockTypeMask))
return false;
if (m_fLookupDirty)
refreshLockedLookups();
if ( (fCheckSelf) && (isLockedFolderEntry(idFolder, eSourceTypeMask, ePermMask, RLV_LOCK_ANY)) )
return true;
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
RlvLockedDescendentsCollector f(eSourceTypeMask, ePermMask, eLockTypeMask);
gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f, FALSE);
return !folders.empty();
}
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
bool RlvFolderLocks::isLockedFolderEntry(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask, ERlvLockMask eLockTypeMask) const
{
for (folderlock_map_t::const_iterator itFolderLock = m_LockedFolderMap.lower_bound(idFolder),
endFolderLock = m_LockedFolderMap.upper_bound(idFolder); itFolderLock != endFolderLock; ++itFolderLock)
{
const folderlock_descr_t* pLockDescr = itFolderLock->second;
if ( (pLockDescr->lockSource.first & eSourceTypeMask) && (pLockDescr->eLockPermission & ePermMask) &&
(pLockDescr->eLockType & eLockTypeMask) )
{
return true;
}
}
return false;
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
bool RlvFolderLocks::isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, folderlock_source_t* plockSource) const
{
// Sanity check - if there are no folder locks then we don't have to actually do anything
if (!hasLockedFolder(eLockTypeMask))
return false;
if (m_fLookupDirty)
refreshLockedLookups();
// Walk up the folder tree and check if anything has 'idFolder' locked
std::list<LLUUID> idsRlvObjRem, idsRlvObjAdd; const LLUUID& idFolderRoot = gInventory.getRootFolderID(); LLUUID idFolderCur = idFolder;
while (idFolderRoot != idFolderCur)
{
// Iterate over any folder locks for 'idFolderCur'
for (folderlock_map_t::const_iterator itFolderLock = m_LockedFolderMap.lower_bound(idFolderCur),
endFolderLock = m_LockedFolderMap.upper_bound(idFolderCur); itFolderLock != endFolderLock; ++itFolderLock)
{
const folderlock_descr_t* pLockDescr = itFolderLock->second;
// We can skip over the current lock if:
// - the current lock type doesn't match eLockTypeMask
// - it's a node lock and the current folder doesn't match
// - we encountered a PERM_ALLOW lock from the current lock owner before which supercedes any subsequent locks
// - the lock source type doesn't match the mask passed in eSourceTypeMask
ERlvLockMask eCurLockType = (ERlvLockMask)(pLockDescr->eLockType & eLockTypeMask);
std::list<LLUUID>* pidRlvObjList = (RLV_LOCK_REMOVE == eCurLockType) ? &idsRlvObjRem : &idsRlvObjAdd;
if ( (0 == eCurLockType) || ((SCOPE_NODE == pLockDescr->eLockScope) && (idFolder != idFolderCur)) ||
(pidRlvObjList->end() != std::find(pidRlvObjList->begin(), pidRlvObjList->end(), pLockDescr->idRlvObj)) ||
(0 == (pLockDescr->eLockType & eSourceTypeMask)) )
{
continue;
}
if (PERM_DENY == pLockDescr->eLockPermission)
{
if (plockSource)
*plockSource = pLockDescr->lockSource;
return true; // Folder is explicitly denied, indicate locked folder to our caller
}
else if (PERM_ALLOW == pLockDescr->eLockPermission)
{
pidRlvObjList->push_back(pLockDescr->idRlvObj); // Folder is explicitly allowed, save the owner so we can skip it from now on
}
}
// Move up to the folder tree
const LLViewerInventoryCategory* pParent = gInventory.getCategory(idFolderCur);
idFolderCur = (pParent) ? pParent->getParentUUID() : idFolderRoot;
}
// If we didn't encounter an explicit deny lock with no exception then the folder is locked if the entire inventory is locked down
return (m_fLockedRoot) && (idsRlvObjRem.empty()) && (idsRlvObjAdd.empty());
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
void RlvFolderLocks::onCOFChanged()
void RlvFolderLocks::onNeedsLookupRefresh()
{
// NOTE: when removeFolderLock() removes the last folder lock we still want to refresh everything so mind the conditional OR assignment
m_fItemsDirty |= (!m_FolderAdd.empty()) || (!m_FolderRem.empty());
m_fLookupDirty |= !m_FolderLocks.empty();
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
void RlvFolderLocks::refreshLockedLookups() const
{
//
// Refresh locked folders
//
m_fLockedRoot = false;
m_LockedFolderMap.clear();
for (folderlock_list_t::const_iterator itFolderLock = m_FolderLocks.begin(); itFolderLock != m_FolderLocks.end(); ++itFolderLock)
{
const folderlock_descr_t* pLockDescr = *itFolderLock;
LLInventoryModel::cat_array_t lockedFolders; const LLUUID& idFolderRoot = gInventory.getRootFolderID();
if (getLockedFolders(pLockDescr->lockSource, lockedFolders))
{
for (S32 idxFolder = 0, cntFolder = lockedFolders.count(); idxFolder < cntFolder; idxFolder++)
{
const LLViewerInventoryCategory* pFolder = lockedFolders.get(idxFolder);
if (idFolderRoot != pFolder->getUUID())
m_LockedFolderMap.insert(std::pair<LLUUID, const folderlock_descr_t*>(pFolder->getUUID(), pLockDescr));
else
m_fLockedRoot |= (SCOPE_SUBTREE == pLockDescr->eLockScope);
}
}
}
m_fLookupDirty = false;
//
// Refresh locked items (iterate over COF and filter out any items residing in a RLV_LOCK_REMOVE locked PERM_DENY folder)
//
m_LockedAttachmentRem.clear();
m_LockedWearableRem.clear();
LLInventoryModel::item_array_t lockedItems;
if (getLockedItems(LLAppearanceMgr::instance().getCOF(), lockedItems, true))
{
for (S32 idxItem = 0, cntItem = lockedItems.count(); idxItem < cntItem; idxItem++)
{
const LLViewerInventoryItem* pItem = lockedItems.get(idxItem);
switch (pItem->getType())
{
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
m_LockedWearableRem.push_back(pItem->getLinkedUUID());
break;
case LLAssetType::AT_OBJECT:
m_LockedAttachmentRem.push_back(pItem->getLinkedUUID());
break;
}
}
}
// Remove any duplicate items we may have picked up
std::sort(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end());
m_LockedAttachmentRem.erase(std::unique(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end()), m_LockedAttachmentRem.end());
std::sort(m_LockedWearableRem.begin(), m_LockedWearableRem.end());
m_LockedWearableRem.erase(std::unique(m_LockedWearableRem.begin(), m_LockedWearableRem.end()), m_LockedWearableRem.end());
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
void RlvFolderLocks::removeFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope,
const LLUUID& idRlvObj, ERlvLockMask eLockType)
{
// Sanity check - eLockType can be RLV_LOCK_ADD or RLV_LOCK_REMOVE but not both
RLV_ASSERT( (RLV_LOCK_ADD == eLockType) || (RLV_LOCK_REMOVE == eLockType) );
folderlock_descr_t lockDescr(idRlvObj, eLockType, lockSource, ePerm, eScope); RlvPredValuesEqual<folderlock_descr_t> f = { &lockDescr };
folderlock_list_t::iterator itFolderLock = std::find_if(m_FolderLocks.begin(), m_FolderLocks.end(), f);
RLV_ASSERT( m_FolderLocks.end() != itFolderLock ); // The lock should always exist
if (m_FolderLocks.end() != itFolderLock)
{
delete *itFolderLock;
m_FolderLocks.erase(itFolderLock);
if (PERM_DENY == ePerm)
{
if (RLV_LOCK_REMOVE == eLockType)
m_cntLockRem--;
else if (RLV_LOCK_ADD == eLockType)
m_cntLockAdd--;
}
m_fLookupDirty = true;
}
}
// ============================================================================

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -17,32 +17,18 @@
#ifndef RLV_LOCKS_H
#define RLV_LOCKS_H
#include "llagentconstants.h"
#include "llagentwearables.h"
#include "lleventtimer.h"
#include "llvoavatarself.h"
#include "rlvdefines.h"
#include "rlvcommon.h"
#ifdef LL_WINDOWS
#pragma warning (push)
#pragma warning (disable : 4702) // warning C4702: unreachable code
#endif
#include <boost/variant.hpp>
#ifdef LL_WINDOWS
#pragma warning (pop)
#endif
// ============================================================================
// RlvAttachPtLookup class declaration
//
#include "llagent.h"
#include "llviewerjointattachment.h"
#include "llviewerobject.h"
#include "llvoavatarself.h"
#include "rlvdefines.h"
class RlvAttachPtLookup
{
public:
@ -116,6 +102,8 @@ protected:
* canAttach/canDetach trivial helper functions (note that a more approriate name might be userCanAttach/userCanDetach)
*/
public:
// Returns TRUE if there is at least one attachment point that can be attached to
bool canAttach() const;
// Returns TRUE if the inventory item can be attached by the user (and optionally provides the attachment point - which may be NULL)
ERlvWearMask canAttach(const LLInventoryItem* pItem, LLViewerJointAttachment** ppAttachPtOut = NULL) const;
// Returns TRUE if the attachment point can be attached to by the user
@ -293,59 +281,98 @@ extern RlvWearableLocks gRlvWearableLocks;
class RlvFolderLocks : public LLSingleton<RlvFolderLocks>
{
friend class RlvLockedDescendentsCollector;
public:
RlvFolderLocks();
// Specifies the source of a folder lock (attachment UUID, shared path, attachment point index or wearable type)
typedef boost::variant<LLUUID, std::string, S32, LLWearableType::EType> rlv_folderlock_source_t;
// Couples the folder lock source with the type of lock (false = folder node ; true = folder subtree)
typedef std::pair<rlv_folderlock_source_t, bool> rlv_folderlock_descr_t;
// Specifies the source of a folder lock
enum ELockSourceType
{
ST_ATTACHMENT = 0x01, ST_ATTACHMENTPOINT = 0x02, ST_FOLDER = 0x04, ST_ROOTFOLDER = 0x08,
ST_SHAREDPATH = 0x10, ST_WEARABLETYPE = 0x20, ST_NONE= 0x00, ST_MASK_ANY = 0xFF
};
typedef boost::variant<LLUUID, std::string, S32, LLWearableType::EType> lock_source_t;
typedef std::pair<ELockSourceType, lock_source_t> folderlock_source_t;
// Specifies options for the folder lock
enum ELockPermission { PERM_ALLOW = 0x1, PERM_DENY = 0x2, PERM_MASK_ANY = 0x3 };
enum ELockScope { SCOPE_NODE, SCOPE_SUBTREE } ;
protected:
struct folderlock_descr_t
{
LLUUID idRlvObj;
ERlvLockMask eLockType;
folderlock_source_t lockSource;
ELockPermission eLockPermission;
ELockScope eLockScope;
folderlock_descr_t(const LLUUID& rlvObj, ERlvLockMask lockType, folderlock_source_t source, ELockPermission perm, ELockScope scope);
bool operator ==(const folderlock_descr_t& rhs) const;
};
public:
// Adds an eLock type lock (held by idRlvObj) for the folder(s) described by lockDescr
void addFolderLock(const rlv_folderlock_descr_t& lockDescr, const LLUUID& idRlvObj, ERlvLockMask eLock);
// Adds an eLock type lock (held by idRlvObj) for the specified folder source (with ePerm and eScope lock options)
void addFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope, const LLUUID& idRlvObj, ERlvLockMask eLockType);
// Returns TRUE if there is at least 1 eLock type locked folder (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE)
bool hasLockedFolder(ERlvLockMask eLock) const;
// Returns TRUE if there is at least 1 non-detachable attachment as a result of a RLV_LOCK_REMOVE folder lock
// Returns TRUE if there is at least 1 non-detachable attachment as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool hasLockedAttachment() const;
// Returns TRUE if there is at least 1 non-removable wearable as a result of a RLV_LOCK_REMOVE folder lock
// Returns TRUE if there is at least 1 eLock type PERM_DENY locked folder (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE)
bool hasLockedFolder(ERlvLockMask eLockTypeMask) const;
// Returns TRUE if the folder has a descendent folder lock with the specified charateristics
bool hasLockedFolderDescendent(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask,
ERlvLockMask eLockTypeMask, bool fCheckSelf) const;
// Returns TRUE if there is at least 1 non-removable wearable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool hasLockedWearable() const;
// Returns TRUE if the attachment (specified by inventory item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder lock
// Returns TRUE if the attachment (specified by item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedAttachment(const LLUUID& idItem) const;
// Returns TRUE if the folder is locked as a result of a RLV_LOCK_REMOVE folder lock
bool isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLock) const;
// Returns TRUE if the wearable (specified by inventory item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder lock
// Returns TRUE if the folder is locked as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, folderlock_source_t* plockSource = NULL) const;
// Returns TRUE if the wearable (specified by item UUID) is non-removable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
bool isLockedWearable(const LLUUID& idItem) const;
// Removes an eLock type lock (held by idRlvObj) for the folder(s) described by lockDescr
void removeFolderLock(const rlv_folderlock_descr_t& lockDescr, const LLUUID& idRlvObj, ERlvLockMask eLock);
// Removes an eLock type lock (held by idRlvObj) for the specified folder source (with ePerm and eScope lock options)
void removeFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope, const LLUUID& idRlvObj, ERlvLockMask eLockType);
protected:
// Returns TRUE if the folder has an explicit folder lock entry with the specified charateristics
bool isLockedFolderEntry(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask, ERlvLockMask eLockTypeMask) const;
/*
* canXXX helper functions (note that a more approriate name might be userCanXXX)
*/
public:
bool canMoveFolder(const LLUUID& idFolder, const LLUUID& idFolderDest) const;
bool canRemoveFolder(const LLUUID& idFolder) const;
bool canRenameFolder(const LLUUID& idFolder) const;
bool canMoveItem(const LLUUID& idItem, const LLUUID& idFolderDest) const;
bool canRemoveItem(const LLUUID& idItem) const;
bool canRenameItem(const LLUUID& idItem) const;
/*
* Cached item/folder look-up helper functions
*/
protected:
void getLockedFolders(const rlv_folderlock_descr_t& lockDescr, LLInventoryModel::cat_array_t& folders) const;
bool getLockedFolders(ERlvLockMask eLock, LLInventoryModel::cat_array_t& nodeFolders, LLInventoryModel::cat_array_t& subtreeFolders) const;
void onCOFChanged();
void refreshLockedItems() const;
void refreshLockedItems(ERlvLockMask eLock, LLInventoryModel::cat_array_t lockFolders, bool fMatchAll) const;
bool getLockedFolders(const folderlock_source_t& lockSource, LLInventoryModel::cat_array_t& lockFolders) const;
bool getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const;
void onNeedsLookupRefresh();
void refreshLockedLookups() const;
/*
* Member variables
*/
protected:
// Map of folder locks (idRlvObj -> lockDescr)
typedef std::multimap<LLUUID, rlv_folderlock_descr_t> rlv_folderlock_map_t;
rlv_folderlock_map_t m_FolderAdd;
rlv_folderlock_map_t m_FolderRem;
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
// Cached item look-up variables
mutable bool m_fItemsDirty;
mutable uuid_vec_t m_LockedFolderAdd;
mutable uuid_vec_t m_LockedAttachmentRem;
mutable uuid_vec_t m_LockedFolderRem;
mutable uuid_vec_t m_LockedWearableRem;
typedef std::multimap<LLUUID, const folderlock_descr_t*> folderlock_map_t;
mutable bool m_fLookupDirty;
mutable bool m_fLockedRoot;
mutable uuid_vec_t m_LockedAttachmentRem;
mutable folderlock_map_t m_LockedFolderMap;
mutable uuid_vec_t m_LockedWearableRem;
private:
friend class LLSingleton<RlvFolderLocks>;
};
@ -391,16 +418,17 @@ inline S32 RlvAttachPtLookup::getAttachPointIndex(const LLViewerObject* pObj)
// RlvAttachmentLocks inlined member functions
//
// Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
// Checked: 2011-05-22 (RLVa-1.3.1b) | Modified: RLVa-1.3.1b
inline ERlvWearMask RlvAttachmentLocks::canAttach(const LLInventoryItem* pItem, LLViewerJointAttachment** ppAttachPtOut /*=NULL*/) const
{
// The specified item can be attached if:
// - it doesn't specify an attachment point
// - it doesn't specify an attachment point and there is at least one attachment point that can be attached to
// - the attachment point it specifies can be attached to
LLViewerJointAttachment* pAttachPt = RlvAttachPtLookup::getAttachPoint(pItem);
if (ppAttachPtOut)
*ppAttachPtOut = pAttachPt;
return (!pAttachPt) ? RLV_WEAR : canAttach(pAttachPt);
return ((canAttach()) && (pItem) && (!RlvFolderLocks::instance().isLockedFolder(pItem->getParentUUID(), RLV_LOCK_ADD)))
? ((!pAttachPt) ? RLV_WEAR : canAttach(pAttachPt)) : RLV_WEAR_LOCKED;
}
// Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
@ -478,12 +506,13 @@ inline bool RlvWearableLocks::canRemove(const LLInventoryItem* pItem) const
return (pWearable) && (!isLockedWearable(pWearable));
}
// Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
inline ERlvWearMask RlvWearableLocks::canWear(const LLViewerInventoryItem* pItem) const
{
// The specified item can be worn if the wearable type it specifies can be worn on
RLV_ASSERT( (pItem) && (LLInventoryType::IT_WEARABLE == pItem->getInventoryType()) );
return (pItem) ? canWear(pItem->getWearableType()) : RLV_WEAR_LOCKED;
return ((pItem) && (!RlvFolderLocks::instance().isLockedFolder(pItem->getParentUUID(), RLV_LOCK_ADD)))
? canWear(pItem->getWearableType()) : RLV_WEAR_LOCKED;
}
// Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
@ -545,52 +574,127 @@ inline void RlvAttachmentLockWatchdog::onWearAttachment(const LLInventoryItem* p
// RlvFolderLocks member functions
//
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline RlvFolderLocks::folderlock_descr_t::folderlock_descr_t(const LLUUID& rlvObj, ERlvLockMask lockType, folderlock_source_t source,
ELockPermission perm, ELockScope scope)
: idRlvObj(rlvObj), eLockType(lockType), lockSource(source), eLockPermission(perm), eLockScope(scope)
{
}
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::folderlock_descr_t::operator ==(const folderlock_descr_t& rhs) const
{
return (idRlvObj == rhs.idRlvObj) && (eLockType == rhs.eLockType) && (lockSource == rhs.lockSource) &&
(eLockPermission == rhs.eLockPermission) && (eLockScope == rhs.eLockScope);
}
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canMoveFolder(const LLUUID& idFolder, const LLUUID& idFolderDest) const
{
// Block moving the folder to destination if:
// - the folder (or one of its descendents) is explicitly locked
// - folder and destination are subject to different locks
// -> Possible combinations:
// * folder locked + destination unlocked => block move
// * folder unlocked + destination locked => block move
// * folder locked + destination locked => allow move only if both are subject to the same folder lock
// * folder unlocked + destination unlocked => allow move (special case of above since both locks are equal when there is none)
// => so the above becomes (isLockedFolder(A) == isLockedFolder(B)) && (lockA == lockB)
folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0);
return
(!hasLockedFolderDescendent(idFolder, ST_MASK_ANY, PERM_MASK_ANY, RLV_LOCK_ANY, true)) &&
( (isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, ST_MASK_ANY, &lockSourceDest)) &&
(lockSource == lockSourceDest) );
}
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canRemoveFolder(const LLUUID& idFolder) const
{
// Block removing a folder if:
// - the folder (or one of its descendents) is explicitly locked
// - the folder itself is locked (but disregard root folder locks)
return
(!hasLockedFolderDescendent(idFolder, ST_MASK_ANY, PERM_MASK_ANY, RLV_LOCK_ANY, true)) &&
(!isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY & ~ST_ROOTFOLDER));
}
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canRenameFolder(const LLUUID& idFolder) const
{
// Block renaming a folder if:
// - the folder (or one of its descendents) is explicitly locked by:
// -> a "shared path" => renaming the folder would change the shared path and hence invalidate the lock
// -> an attachment point \
// -> an attachment |--> renaming the folder to a "dot" (=invisible) folder would invalidate the lock
// -> a wearable type /
return !hasLockedFolderDescendent(idFolder, ST_SHAREDPATH | ST_ATTACHMENT | ST_ATTACHMENTPOINT | ST_WEARABLETYPE, PERM_MASK_ANY, RLV_LOCK_ANY, true);
}
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canMoveItem(const LLUUID& idItem, const LLUUID& idFolderDest) const
{
// Block moving the folder to destination if:
// - folder and destination are subject to different locks [see canMoveFolder() for more details]
const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); const LLUUID& idFolder = (pItem) ? pItem->getParentUUID() : LLUUID::null;
int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER; folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0);
return
(idFolder.notNull()) &&
(isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, maskSource, &lockSourceDest)) &&
(lockSource == lockSourceDest);
}
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canRemoveItem(const LLUUID& idItem) const
{
// Block removing items from locked folders (but disregard root folder locks)
const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); const LLUUID& idFolder = (pItem) ? pItem->getParentUUID() : LLUUID::null;
int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER;
return (idFolder.notNull()) && (!isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource));
}
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
inline bool RlvFolderLocks::canRenameItem(const LLUUID& idItem) const
{
// Items can always be renamed, regardless of folder locks
return true;
}
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
inline bool RlvFolderLocks::hasLockedAttachment() const
{
if (m_fItemsDirty)
refreshLockedItems();
if (m_fLookupDirty)
refreshLockedLookups();
return !m_LockedAttachmentRem.empty();
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
inline bool RlvFolderLocks::hasLockedFolder(ERlvLockMask eLock) const
{
// Remove locks are more common so check those first
return ((eLock & RLV_LOCK_REMOVE) && (!m_FolderRem.empty())) || ((eLock & RLV_LOCK_ADD) && (!m_FolderAdd.empty()));
return ((eLock & RLV_LOCK_REMOVE) && (m_cntLockRem)) || ((eLock & RLV_LOCK_ADD) && (m_cntLockAdd));
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
inline bool RlvFolderLocks::hasLockedWearable() const
{
if (m_fItemsDirty)
refreshLockedItems();
if (m_fLookupDirty)
refreshLockedLookups();
return !m_LockedWearableRem.empty();
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
inline bool RlvFolderLocks::isLockedAttachment(const LLUUID& idItem) const
{
if (m_fItemsDirty)
refreshLockedItems();
if (m_fLookupDirty)
refreshLockedLookups();
return (std::find(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end(), idItem) != m_LockedAttachmentRem.end());
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
inline bool RlvFolderLocks::isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLock) const
{
if (m_fItemsDirty)
refreshLockedItems();
return
( (eLock & RLV_LOCK_REMOVE) && (std::find(m_LockedFolderRem.begin(), m_LockedFolderRem.end(), idFolder) != m_LockedFolderRem.end()) ) ||
( (eLock & RLV_LOCK_ADD) && (std::find(m_LockedFolderAdd.begin(), m_LockedFolderAdd.end(), idFolder) != m_LockedFolderAdd.end()) );
}
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
inline bool RlvFolderLocks::isLockedWearable(const LLUUID& idItem) const
{
if (m_fItemsDirty)
refreshLockedItems();
if (m_fLookupDirty)
refreshLockedLookups();
return (std::find(m_LockedWearableRem.begin(), m_LockedWearableRem.end(), idItem) != m_LockedWearableRem.end());
}

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -15,6 +15,7 @@
*/
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llavatarlist.h" // Avatar list control used by the "Nearby" tab in the "People" sidebar panel
#include "llavatarnamecache.h"
#include "llbottomtray.h"
@ -40,6 +41,7 @@
#include "llteleporthistorystorage.h"
#include "lltoolmgr.h"
#include "llviewerparcelmgr.h"
#include "llvoavatar.h"
#include "roles_constants.h" // Group "powers"
#include "rlvui.h"
@ -51,7 +53,7 @@
RlvUIEnabler::RlvUIEnabler()
{
// Connect us to the behaviour toggle signal
gRlvHandler.setBehaviourCallback(boost::bind(&RlvUIEnabler::onBehaviour, this, _1, _2));
gRlvHandler.setBehaviourToggleCallback(boost::bind(&RlvUIEnabler::onBehaviourToggle, this, _1, _2));
// onRefreshHoverText()
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SHOWLOC, boost::bind(&RlvUIEnabler::onRefreshHoverText, this)));
@ -66,7 +68,6 @@ RlvUIEnabler::RlvUIEnabler()
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_VIEWTEXTURE, boost::bind(&RlvUIEnabler::onToggleViewXXX, this)));
// onToggleXXX
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_DISPLAYNAME, boost::bind(&RlvUIEnabler::onToggleDisplayName, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_EDIT, boost::bind(&RlvUIEnabler::onToggleEdit, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_FLY, boost::bind(&RlvUIEnabler::onToggleFly, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_REZ, boost::bind(&RlvUIEnabler::onToggleRez, this)));
@ -90,19 +91,13 @@ RlvUIEnabler::RlvUIEnabler()
}
// Checked: 2010-02-28 (RLVa-1.2.0b) | Added: RLVa-1.2.0a
void RlvUIEnabler::onBehaviour(ERlvBehaviour eBhvr, ERlvParamType eType)
void RlvUIEnabler::onBehaviourToggle(ERlvBehaviour eBhvr, ERlvParamType eType)
{
bool fQuitting = LLApp::isQuitting();
// We're only interested in behaviour toggles (ie on->off or off->on)
if ( ((RLV_TYPE_ADD == eType) && (1 == gRlvHandler.hasBehaviour(eBhvr))) ||
((RLV_TYPE_REMOVE == eType) && (0 == gRlvHandler.hasBehaviour(eBhvr))) )
for (behaviour_handler_map_t::const_iterator itHandler = m_Handlers.lower_bound(eBhvr), endHandler = m_Handlers.upper_bound(eBhvr);
itHandler != endHandler; ++itHandler)
{
for (behaviour_handler_map_t::const_iterator itHandler = m_Handlers.lower_bound(eBhvr), endHandler = m_Handlers.upper_bound(eBhvr);
itHandler != endHandler; ++itHandler)
{
itHandler->second(fQuitting);
}
itHandler->second(fQuitting);
}
}
@ -115,25 +110,6 @@ void RlvUIEnabler::onRefreshHoverText()
LLHUDText::refreshAllObjectText();
}
// Checked: 2010-11-02 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
void RlvUIEnabler::onToggleDisplayName()
{
static const char cstrFloaterChangeDisplayName[] = "display_name";
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_DISPLAYNAME);
if (!fEnable)
{
// Hide the "Change Display Name" floater if it's currently visible
if (LLFloaterReg::floaterInstanceVisible(cstrFloaterChangeDisplayName))
LLFloaterReg::hideInstance(cstrFloaterChangeDisplayName);
}
if (!fEnable)
addGenericFloaterFilter(cstrFloaterChangeDisplayName);
else
removeGenericFloaterFilter(cstrFloaterChangeDisplayName);
}
// Checked: 2010-03-17 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvUIEnabler::onToggleEdit()
{
@ -358,18 +334,18 @@ void RlvUIEnabler::onToggleShowLoc()
m_ConnFloaterShowLoc.disconnect();
}
// Checked: 2010-02-28 (RLVa-1.2.0b) | Added: RLVa-1.2.0a
// Checked: 2011-05-22 (RLVa-1.3.1b) | Modified: RLVa-1.3.1b
void RlvUIEnabler::onToggleShowMinimap()
{
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP);
// Start or stop filtering opening the mini-map
// Start or stop filtering showing the mini-map floater
if (!fEnable)
addGenericFloaterFilter("mini_map");
else
removeGenericFloaterFilter("mini_map");
// Hide the mini-map if it's currently visible (or restore it if it was previously visible)
// Hide the mini-map floater if it's currently visible (or restore it if it was previously visible)
static bool fPrevVisibile = false;
if ( (!fEnable) && ((fPrevVisibile = LLFloaterReg::floaterInstanceVisible("mini_map"))) )
LLFloaterReg::hideFloaterInstance("mini_map");
@ -381,6 +357,18 @@ void RlvUIEnabler::onToggleShowMinimap()
LLView* pBtnView = (pTray) ? pTray->getChildView("mini_map_btn") : NULL;
if (pBtnView)
pBtnView->setEnabled(fEnable);
// Break/reestablish the visibility connection for the nearby people panel embedded minimap instance
LLPanel* pPeoplePanel = LLSideTray::getInstance()->getPanel("panel_people");
LLPanel* pNetMapPanel = (pPeoplePanel) ? pPeoplePanel->getChild<LLPanel>("Net Map Panel", 1) : NULL;
RLV_ASSERT( (pPeoplePanel) && (pNetMapPanel) );
if (pNetMapPanel)
{
pNetMapPanel->setMakeVisibleControlVariable( (fEnable) ? gSavedSettings.getControl("NearbyListShowMap") : NULL);
// Reestablishing the visiblity connection will show the panel if needed so we only need to take care of hiding it when needed
if ( (!fEnable) && (pNetMapPanel->getVisible()) )
pNetMapPanel->setVisible(false);
}
}
// Checked: 2010-12-08 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2009-2010, Kitty Barnett
* Copyright (c) 2009-2011, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
@ -39,14 +39,13 @@ protected:
public:
typedef boost::function<void(bool)> behaviour_handler_t;
void addBehaviourToggleCallback(ERlvBehaviour eBhvr, behaviour_handler_t cb);
void onBehaviour(ERlvBehaviour eBhvr, ERlvParamType eType); // RlvHandler::rlv_behaviour_signal_t
void onBehaviourToggle(ERlvBehaviour eBhvr, ERlvParamType eType); // RlvHandler::rlv_behaviour_signal_t
/*
* Behaviour handlers
*/
protected:
void onRefreshHoverText(); // showloc, shownames, showhovertext(all|world|hud)
void onToggleDisplayName(); // displayname
void onToggleEdit(); // edit
void onToggleFly(); // fly
void onToggleRez(); // rez

View File

@ -1,10 +1,87 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true"
height="425" min_height="200" min_width="375" name="rlv_behaviours" title="Active RLV Restrictions" width="350"
save_rect="true" save_visibility="true" single_instance="true">
<scroll_list top="0" draw_border="false" follows="top|left|bottom|right" height="400" multi_select="false"
name="behaviour_list" draw_heading="true" draw_stripes="true" layout="topleft">
<scroll_list.columns label="Restriction" name="behaviour" width="170" />
<scroll_list.columns label="Object Name" name="name" width="170" />
</scroll_list>
<floater
can_close="true"
can_drag_on_left="false"
can_minimize="true"
can_resize="true"
height="455"
min_height="200"
min_width="375"
name="rlv_behaviours"
save_rect="true"
save_visibility="true"
single_instance="true"
title="Active RLV Restrictions"
width="350">
<tab_container
follows="all"
top="10"
left="10"
height="405"
width="330"
name="behaviour_tab"
tab_position="top"
layout="topleft">
<panel
border="true"
label="Restrictions"
name="behaviour_panel">
<scroll_list
top_pad="17"
follows="all"
draw_border="false"
multi_select="false"
name="behaviour_list"
draw_heading="true"
draw_stripes="true"
layout="topleft">
<scroll_list.columns
label="Restriction"
name="behaviour"
width="170" />
<scroll_list.columns
label="Object Name"
name="issuer"
width="170" />
</scroll_list>
</panel>
<panel
border="true"
label="Exceptions"
name="exception_panel">
<scroll_list
top_pad="17"
follows="all"
draw_border="false"
multi_select="false"
name="exception_list"
draw_heading="true"
draw_stripes="true"
layout="topleft">
<scroll_list.columns
label="Restriction"
name="behaviour"
width="70" />
<scroll_list.columns
label="Option"
name="option"
width="170" />
<scroll_list.columns
label="Object Name"
name="issuer"
width="170" />
</scroll_list>
</panel>
</tab_container>
<button
follows="bottom|left"
height="25"
label="Copy to Clipboard"
left="10"
name="copy_btn"
top_pad="5"
width="180" />
</floater>

View File

@ -42,6 +42,17 @@
function="CheckControl"
parameter="NearbyListShowIcons" />
</menu_item_check>
<menu_item_check name ="view_map" label="View Map">
<menu_item_check.on_check
function="CheckControl"
parameter="NearbyListShowMap" />
<menu_item_check.on_click
function="ToggleControl"
parameter="NearbyListShowMap" />
<menu_item_check.on_enable
function="RLV.EnableIfNot"
parameter="showminimap" />
</menu_item_check>
<menu_item_separator layout="topleft" />
<menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
<menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" />

View File

@ -5682,6 +5682,7 @@ Do you want to keep it? "Block" will block any more offers or messages from [NAM
<notification
icon="notify.tga"
name="UserGiveItem"
label="Inventory offer from [NAME_LABEL]"
type="offer">
[NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
@ -5737,6 +5738,7 @@ Do you want to keep it? "Block" will block any more offers or messages from [NAM
<notification
icon="notify.tga"
name="TeleportOffered"
label="Teleport offer from [NAME_LABEL]"
type="offer">
[NAME_SLURL] has offered to teleport you to their location:
@ -5783,6 +5785,7 @@ Do you want to keep it? "Block" will block any more offers or messages from [NAM
<notification
icon="notify.tga"
name="OfferFriendship"
label="Friendship offer from [NAME_LABEL]"
type="offer">
[NAME_SLURL] is offering friendship.
@ -5811,6 +5814,7 @@ Do you want to keep it? "Block" will block any more offers or messages from [NAM
<notification
icon="notify.tga"
name="OfferFriendshipNoMessage"
label="Friendship offer from [NAME_LABEL]"
persist="true"
type="notify">
[NAME_SLURL] is offering friendship.

View File

@ -76,7 +76,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
follows="all"
height="383"
layout="topleft"
left="5"
left="3"
name="tabs"
tab_group="1"
tab_min_width="70"
@ -84,7 +84,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
tab_position="top"
top_pad="10"
halign="center"
width="317">
width="319">
<panel
background_opaque="false"
background_visible="true"
@ -100,16 +100,40 @@ Looking for people to hang out with? Use the search box to find topics or conten
top="0"
width="313">
<layout_stack
clip="false"
follows="all"
height="355"
layout="topleft"
mouse_opaque="false"
orientation="vertical"
width="313">
<layout_panel
height="142"
layout="topleft"
mouse_opaque="false"
name="Net Map Panel"
user_resize="false"
visibility_control="NearbyListShowMap"
width="313">
<net_map
bg_color="NetMapBackgroundColor"
follows="top|left|right"
follows="all"
height="140"
layout="topleft"
left="3"
mouse_opaque="false"
name="Net Map"
width="307"
height="140"
top="0"/>
top="4"
width="305"/>
</layout_panel>
<layout_panel
height="213"
layout="topleft"
min_height="100"
mouse_opaque="false"
user_resize="false"
width="313">
<panel
height="15"
@ -165,17 +189,20 @@ Looking for people to hang out with? Use the search box to find topics or conten
follows="left|right|top" />
<avatar_list
allow_select="true"
follows="all"
height="336"
ignore_online_status="true"
layout="topleft"
left="3"
multi_select="true"
name="avatar_list"
top_pad="0"
width="307" />
<panel
allow_select="true"
follows="all"
height="211"
ignore_online_status="true"
layout="topleft"
left="3"
keep_one_selected="false"
multi_select="true"
name="avatar_list"
top="2"
width="306" />
</layout_panel>
</layout_stack>
<panel
background_visible="true"
follows="left|right|bottom"
height="27"
@ -354,7 +381,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
top_pad="1"
left="0"
name="bottom_panel"
width="305">
width="308">
<layout_panel
auto_resize="false"
height="25"
@ -419,7 +446,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
layout="topleft"
name="dummy_panel"
user_resize="false"
width="212">
width="210">
<icon
follows="bottom|left|right"
height="25"
@ -428,7 +455,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
left="0"
top="0"
name="dummy_icon"
width="211" />
width="210" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -590,7 +617,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
layout="topleft"
left_pad="1"
name="dummy_icon"
width="209"
width="212"
/>
</panel>
</panel>
@ -625,7 +652,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
height="27"
label="bottom_panel"
layout="topleft"
left="0"
left="3"
name="bottom_panel"
top_pad="0"
width="313">
@ -664,7 +691,7 @@ Looking for people to hang out with? Use the search box to find topics or conten
layout="topleft"
left_pad="1"
name="dummy_icon"
width="241"
width="244"
/>
</panel>
</panel>

View File

@ -13,6 +13,8 @@
<!-- Shown as notifications -->
<string name="blocked_generic">Unable to perform action due to RLV restrictions</string>
<string name="blocked_startim">Unable to start IM session with [RECIPIENT] due to RLV restrictions</string>
<string name="blocked_startconf">Unable to start conference with [RECIPIENT] due to RLV restrictions</string>
<string name="blocked_teleport">Unable to initiate teleport due to RLV restrictions</string>
<string name="blocked_viewxxx">Unable to open [TYPE] due to RLV restrictions</string>