diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index dc8b1f7633..749b3f9864 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -734,6 +734,14 @@ void LLAvatarActions::csr(const LLUUID& id, std::string name) //static void LLAvatarActions::share(const LLUUID& id) { +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(id)) ) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", id)); + return; + } +// [/RLVa:KB] + // FIRE-8804: Prevent opening inventory from using share in radar context menu if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV)) { @@ -987,10 +995,34 @@ namespace action_give_inventory * @param avatar_names - avatar names request to be sent. * @param avatar_uuids - avatar names request to be sent. */ - static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector avatar_names, LLInventoryPanel* panel = NULL) +// static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector avatar_names, LLInventoryPanel* panel = NULL) +// [RLVa:KB] - @share + static void give_inventory(uuid_vec_t avatar_uuids, std::vector avatar_names, LLInventoryPanel* panel = NULL) +// [/RLVa:KB] { llassert(avatar_names.size() == avatar_uuids.size()); +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (RlvActions::hasBehaviour(RLV_BHVR_SHARE)) ) + { + for (int idxAvatar = avatar_uuids.size() - 1; idxAvatar >= 0; idxAvatar--) + { + if (!RlvActions::canGiveInventory(avatar_uuids[idxAvatar])) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", avatar_uuids[idxAvatar], "completename").getSLURLString())); + + avatar_uuids.erase(avatar_uuids.begin() + idxAvatar); + avatar_names.erase(avatar_names.begin() + idxAvatar); + } + } + } + + if (avatar_uuids.empty()) + { + return; + } +// [/RLVa:KB] + const std::set inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel); if (inventory_selected_uuids.empty()) { @@ -1116,6 +1148,14 @@ std::set LLAvatarActions::getInventorySelectedUUIDs(LLInventoryPanel* ac //static void LLAvatarActions::shareWithAvatars(LLView * panel) { +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory()) ) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::ShareGeneric); + return; + } +// [/RLVa:KB] + using namespace action_give_inventory; LLFloater* root_floater = gFloaterView->getParentFloater(panel); diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 6966be90ce..c1563ac89f 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -49,6 +49,7 @@ #include "llvoavatarself.h" // [RLVa:KB] - Checked: RLVa-1.2.2 #include "llavatarnamecache.h" +#include "llslurl.h" #include "rlvactions.h" #include "rlvcommon.h" #include "rlvui.h" @@ -201,7 +202,10 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, if (item->getPermissions().allowCopyBy(gAgentID)) { // just give it away. - LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id); +// [RLVa:KB] - @share + res = LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id); +// [/RLVa:KB] +// LLGiveInventory::commitGiveInventoryItem(to_agent, item, im_session_id); } else { @@ -376,6 +380,14 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL switch(option) { case 0: // "Yes" +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) ) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString())); + return false; + } +// [/RLVa:KB] + for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++) { item = gInventory.getItem((*it).asUUID()); @@ -409,11 +421,24 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL } // static -void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, +//void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, +// const LLInventoryItem* item, +// const LLUUID& im_session_id) +// [RLVa:KB] - @share +bool LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID& im_session_id) +// [/RLVa:KB] { - if (!item) return; +// if (!item) return; +// [RLVa:KB] - @share + if (!item) return false; + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) ) + { + return false; + } +// [/RLVa:KB] + std::string name; std::string item_name = item->getName(); LLAgentUI::buildFullname(name); @@ -467,6 +492,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, { LLRecentPeople::instance().add(to_agent); } + return true; // [/RLVa:KB] } @@ -482,6 +508,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID()); if (cat) { +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(notification["payload"]["agent_id"].asUUID())) ) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", notification["payload"]["agent_id"], "completename").getSLURLString())); + return false; + } +// [/RLVa:KB] + give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(), cat); LLViewerInventoryCategory::cat_array_t cats; @@ -529,6 +563,13 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent, { return false; } +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(to_agent)) ) + { + return false; + } +// [/RLVa:KB] + LL_INFOS() << "LLGiveInventory::commitGiveInventoryCategory() - " << cat->getUUID() << LL_ENDL; diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h index 20e6df76e5..86919f9010 100644 --- a/indra/newview/llgiveinventory.h +++ b/indra/newview/llgiveinventory.h @@ -82,9 +82,14 @@ private: const std::string& item_name = std::string(), bool is_folder = false); - static void commitGiveInventoryItem(const LLUUID& to_agent, +// [RLVa:KB] - @share + static bool commitGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID &im_session_id = LLUUID::null); +// [/RLVa:KB] +// static void commitGiveInventoryItem(const LLUUID& to_agent, +// const LLInventoryItem* item, +// const LLUUID &im_session_id = LLUUID::null); // give inventory category functionality static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 4d8e4b8866..ac6c0abccf 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -78,13 +78,11 @@ const F32 PARCEL_POST_HEIGHT = 0.666f; // Returns true if you got at least one object void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { -// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c +// [RLVa:KB] - @edit* and @interact // Block rectangle selection if: - // - prevented from editing and no exceptions are set (see below for the case where exceptions are set) + // - prevented from editing anything at all // - prevented from interacting at all - if ( (rlv_handler_t::isEnabled()) && - ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || - (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) ) + if (RlvActions::isRlvEnabled() && (RlvActions::canEdit(ERlvCheckType::None) || RlvActions::hasBehaviour(RLV_BHVR_INTERACT)) ) { return; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 90dcb751eb..5b0e9c3e73 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -6565,6 +6565,19 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, BOOL rv = FALSE; if(item) { +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(item->getCreatorUUID())) ) + { + if (drop) + { + RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Share, LLSD().with("RECIPIENT", LLSLURL("agent", item->getCreatorUUID(), "completename").getSLURLString())); + } + // We should return false but our caller uses the return value as both 'will accept' *and* 'was handled' so + // returning false will result in the dropped item being moved when it is blocked. + return true; + } +// [/RLVa:KB] + // check the type switch(cargo_type) { diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index e50f137fbb..36b64c04e9 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -4553,8 +4553,9 @@ void LLSelectMgr::convertTransient() void LLSelectMgr::deselectAllIfTooFar() { -// [RLVa:KB] - Checked: RLVa-1.3.0 - if ( (!mSelectedObjects->isEmpty()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) ) +// [RLVa:KB] - @edit* + // Continuously verify the selection as soon as there is at least one prim we shouldn't be able to edit + if ( !mSelectedObjects->isEmpty() && RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All) ) { struct NotTransientOrFocusedMediaOrEditable : public LLSelectedNodeFunctor { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index aa51c67b13..77d7c9bbca 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -61,6 +61,7 @@ #include "llworld.h" #include "llpanelface.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -1650,6 +1651,14 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ EAcceptance* accept, const LLSD& dest) { +// [RLVa:KB] - @share + if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(dest_agent)) ) + { + *accept = ACCEPT_NO_LOCKED; + return true; + } +// [/RLVa:KB] + // check the type switch(cargo_type) { @@ -2473,6 +2482,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject( } if( obj && avatar ) { +// [RLVa:KB] - @share + if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) ) + { + return ACCEPT_NO_LOCKED; + } +// [/RLVa:KB] if(drop) { LLGiveInventory::doGiveInventoryItem(obj->getID(), item ); @@ -2499,6 +2514,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventory( { return ACCEPT_NO; } +// [RLVa:KB] - @share + if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) ) + { + return ACCEPT_NO_LOCKED; + } +// [/RLVa:KB] if (drop && obj) { LLGiveInventory::doGiveInventoryItem(obj->getID(), item); @@ -2512,6 +2533,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { LL_DEBUGS() << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << LL_ENDL; +// [RLVa:KB] - @share + if ( (obj) && (RlvActions::isRlvEnabled()) && (!RlvActions::canGiveInventory(obj->getID())) ) + { + return ACCEPT_NO_LOCKED; + } +// [/RLVa:KB] if(drop && obj) { LLViewerInventoryItem* item; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b914e177a5..c81b29fc4f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3638,17 +3638,19 @@ bool enable_object_edit() } else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound()) { -// enable = true; -// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c - bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ)); - if (!fRlvCanEdit) +// [RLVa:KB] - @edit* + if (RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All)) { LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); RlvSelectIsEditable f; - fRlvCanEdit = (hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) == NULL); + enable = (hSel.notNull()) && (!hSel->getFirstRootNode(&f, true)); + } + else + { + enable = true; } - enable = fRlvCanEdit; // [/RLVa:KB] +// enable = true; } return enable; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8e64265bf2..be66720237 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1022,7 +1022,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mFXAABuffer.release(); } - if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) +// if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) +// [RLVa:KB] - @setsphere + if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0 || RlvActions::hasPostProcess()) +// [/RLVa:KB] { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; } diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 690250c164..a0b100d091 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -18,6 +18,7 @@ #include "llagent.h" #include "llimview.h" #include "llviewercamera.h" +#include "llvisualeffect.h" #include "llvoavatarself.h" #include "llworld.h" @@ -133,6 +134,20 @@ bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject) return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject); } +bool RlvActions::canGiveInventory() +{ + // User can give at least one (unspecified) avatar inventory if: + // - not specifically restricted from giving inventory (or at least one exception exists) + return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.hasException(RLV_BHVR_SHARE)); +} + +bool RlvActions::canGiveInventory(const LLUUID& idAgent) +{ + // User can give another avatar inventory if: + // - not specifically restricted from giving inventory (or the target is an exception) + return (!gRlvHandler.hasBehaviour(RLV_BHVR_SHARE)) || (gRlvHandler.isException(RLV_BHVR_SHARE, idAgent)); +} + // Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist) static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax) { @@ -385,6 +400,11 @@ bool RlvActions::canChangeEnvironment(const LLUUID& idRlvObject) return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETENV, idRlvObject); } +bool RlvActions::hasPostProcess() +{ + return LLVfxManager::instance().hasEffect(EVisualEffect::RlvSphere); +} + // ============================================================================ // World interaction // @@ -407,19 +427,53 @@ bool RlvActions::canBuyObject(const LLUUID& idObj) return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_BUY)); } -// Handles: @edit and @editobj +// Handles: @edit, @editobj, @editattach and @editworld +bool RlvActions::canEdit(ERlvCheckType eCheckType) +{ + RlvHandler& rlvHandler = RlvHandler::instance(); + switch (eCheckType) + { + case ERlvCheckType::All: + // No edit restrictions of any kind + return + !rlvHandler.hasBehaviour(RLV_BHVR_EDIT) && !rlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ) && + !rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) && !rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD); + + case ERlvCheckType::Some: + // Not @edit restricted (or at least one exception) and either not @editattach or not @editworld restricted + return + (!rlvHandler.hasBehaviour(RLV_BHVR_EDIT) || rlvHandler.hasException(RLV_BHVR_EDIT)) && + (!rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) || rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD)); + + case ERlvCheckType::None: + // Either @edit restricted with no exceptions or @editattach and @editworld restricted at the same time + return + (rlvHandler.hasBehaviour(RLV_BHVR_EDIT) && !rlvHandler.hasException(RLV_BHVR_EDIT)) || + (rlvHandler.hasBehaviour(RLV_BHVR_EDITATTACH) && rlvHandler.hasBehaviour(RLV_BHVR_EDITWORLD)); + + default: + RLV_ASSERT(false); + return false; + } +} + +// Handles: @edit, @editobj, @editattach and @editworld bool RlvActions::canEdit(const LLViewerObject* pObj) { // User can edit the specified object if: // - not generally restricted from editing (or the object's root is an exception) // - not specifically restricted from editing this object's root + // - it's an attachment and not restricted from editing attachments + // it's a rezzed object and not restricted from editing any world objects // NOTE-RLVa: edit checks should *never* be subject to @fartouch distance checks since we don't have the pick offset so // instead just implicitly rely on the presence of a (transient) selection return (pObj) && ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDIT)) || (RlvHandler::instance().isException(RLV_BHVR_EDIT, pObj->getRootEdit()->getID())) ) && - ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITOBJ)) || (!RlvHandler::instance().isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())) ); + ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITOBJ)) || (!RlvHandler::instance().isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())) ) && + ( (pObj->isAttachment()) ? !RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITATTACH) + : !RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITWORLD) ); } // Handles: @fartouch and @interact @@ -466,6 +520,12 @@ bool RlvActions::canGroundSit() return (!hasBehaviour(RLV_BHVR_SIT)) && (canStand()); } +bool RlvActions::canGroundSit(const LLUUID& idRlvObjExcept) +{ + // See canGroundSit() but disregard any restrictions held by the issuing object + return (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SIT, idRlvObjExcept)) && (canStand(idRlvObjExcept)); +} + bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) { // User can sit on the specified object if: @@ -519,8 +579,8 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset // (2) Attachment (on another avatar) // - a) not prevented from touching any object // - b) not specifically prevented from touching that object - // - d) not prevented from touching attachments (or the attachment is an exception) - // - e) not prevented from touching other avatar's attachments (or the attachment is an exception) + // - d) not prevented from touching attachments (or the attachment and/or its wearer is/are an exception) + // - e) not prevented from touching other avatar's attachments (or the attachment is worn by a specific avatar on the exception list) // - h) not prevented from touching faraway objects (or the attachment's center + pick offset is within range) // - i) specifically allowed to touch that object (overrides all restrictions) // (3) Attachment (on own avatar) @@ -538,7 +598,7 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset // NOTE-RLVa: * touch restrictions apply linkset-wide (as opposed to, for instance, hover text which is object-specific) but only the root object's restrictions are tested // * @touchall affects world objects and world attachments (self and others') but >not< HUD attachments // * @fartouch distance matches against the specified object + pick offset (so >not< the linkset root) - // * @touchattachother exceptions are only checked under the general @touchattach exceptions + // * @touchattachother exceptions change when they specify an avatar id (=block all) or an object id (=allow indiviual - see general @touchattach exceptions) // * @touchattachself exceptions are only checked under the general @touchattach exceptions // * @touchme in any object of a linkset affects that entire linkset (= if you can specifically touch one prim in a linkset you can touch that entire linkset) const LLUUID& idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null; @@ -551,12 +611,23 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset ( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHTHIS)) || (!rlvHandler.isException(RLV_BHVR_TOUCHTHIS, idRoot, ERlvExceptionCheck::Permissive)) ); if (fCanTouch) { - if ( (!pObj->isAttachment()) || (!pObj->permYouOwner()) ) + if (!pObj->isAttachment()) { - // Rezzed or attachment worn by other - test for (1.c), (2.d), (2.e) and (1/2.h) + // Rezzed object - test for (1.c) and (1.h) fCanTouch = - ( (!pObj->isAttachment()) ? (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (rlvHandler.isException(RLV_BHVR_TOUCHWORLD, idRoot, ERlvExceptionCheck::Permissive)) - : ((!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH)) && (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER))) || (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, ERlvExceptionCheck::Permissive)) ) && + ( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (rlvHandler.isException(RLV_BHVR_TOUCHWORLD, idRoot, ERlvExceptionCheck::Permissive)) ) && + ( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist) ); + } + else if (!pObj->permYouOwner()) + { + // Attachment worn by other - test for (2.d), (2.e) and (2.h) + const LLUUID& idAttachAgent = static_cast(pObj->getRoot())->getID(); + fCanTouch = + ( + ( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH) && !rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER)) || + (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, ERlvExceptionCheck::Permissive) || rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idAttachAgent, ERlvExceptionCheck::Permissive)) ) && + (!rlvHandler.isException(RLV_BHVR_TOUCHATTACHOTHER, idAttachAgent)) + ) && ( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist) ); } else if (!pObj->isHUDAttachment()) diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 39fd2beac7..76d9777894 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -34,6 +34,8 @@ class LLVOAvatar; // RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible // +enum class ERlvCheckType { All, Some, None }; + class RlvActions { // ====== @@ -90,6 +92,16 @@ public: */ static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null); + /* + * Returns true if the user is allowed to give inventory to at least one (unspecified) avatar (used to blanket ban use of 'Share' if the user cannot give items to *anyone*) + */ + static bool canGiveInventory(); + + /* + * Returns true if the user is allowed to give the specified avatar inventory + */ + static bool canGiveInventory(const LLUUID& idAgent); + /* * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group) */ @@ -225,6 +237,10 @@ public: */ static bool canChangeEnvironment(const LLUUID& idRlvObject = LLUUID::null); + /* + * Returns true if a postprocessing shader is currently active + */ + static bool hasPostProcess(); // ================= // World interaction @@ -246,6 +262,11 @@ public: */ static bool canBuyObject(const LLUUID& idObj); + /* + * Returns true if the user can edit all, some, or nothing (used to bail early, or to skip expensive selection checks) + */ + static bool canEdit(ERlvCheckType eCheckType); + /* * Returns true if the user can edit the specified object (with an optional relative offset) */ @@ -255,6 +276,7 @@ public: * Returns true if the user can sit on the ground */ static bool canGroundSit(); + static bool canGroundSit(const LLUUID& idRlvObjExcept); /* * Returns true if the user can interact with the specified object (with an optional relative offset) diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index c0e19fe324..329138cca8 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -129,6 +129,7 @@ enum ERlvBehaviour { RLV_BHVR_SENDGESTURE, RLV_BHVR_PERMISSIVE, // "permissive" RLV_BHVR_NOTIFY, // "notify" + RLV_BHVR_SHARE, RLV_BHVR_SHOWINV, // "showinv" RLV_BHVR_SHOWMINIMAP, // "showminimap" RLV_BHVR_SHOWWORLDMAP, // "showworldmap" @@ -156,7 +157,9 @@ enum ERlvBehaviour { RLV_BHVR_ALLOWIDLE, // "allowidle" RLV_BHVR_BUY, // "buy" RLV_BHVR_EDIT, // "edit" + RLV_BHVR_EDITATTACH, RLV_BHVR_EDITOBJ, // "editobj" + RLV_BHVR_EDITWORLD, RLV_BHVR_VIEWTRANSPARENT, RLV_BHVR_VIEWWIREFRAME, RLV_BHVR_PAY, // "pay" @@ -176,6 +179,7 @@ enum ERlvBehaviour { RLV_BHVR_SETGROUP, // "setgroup" RLV_BHVR_UNSIT, // "unsit" RLV_BHVR_SIT, // "sit" + RLV_BHVR_SITGROUND, RLV_BHVR_SITTP, // "sittp" RLV_BHVR_STANDTP, // "standtp" RLV_BHVR_SETDEBUG, // "setdebug" @@ -459,6 +463,8 @@ namespace RlvStringKeys /*inline*/ constexpr boost::string_view RecvIm = make_string_view("blocked_recvim"); /*inline*/ constexpr boost::string_view RecvImRemote = make_string_view("blocked_recvim_remote"); /*inline*/ constexpr boost::string_view SendIm = make_string_view("blocked_sendim"); + /*inline*/ constexpr boost::string_view Share = make_string_view("blocked_share"); + /*inline*/ constexpr boost::string_view ShareGeneric = make_string_view("blocked_share_generic"); /*inline*/ constexpr boost::string_view StartConference = make_string_view("blocked_startconf"); /*inline*/ constexpr boost::string_view StartIm = make_string_view("blocked_startim"); /*inline*/ constexpr boost::string_view Teleport = make_string_view("blocked_teleport"); @@ -476,6 +482,8 @@ namespace RlvStringKeys constexpr const char RecvIm[] = "blocked_recvim"; constexpr const char RecvImRemote[] = "blocked_recvim_remote"; constexpr const char SendIm[] = "blocked_sendim"; + constexpr const char Share[] = "blocked_share"; + constexpr const char ShareGeneric[] = "blocked_share_generic"; constexpr const char StartConference[] = "blocked_startconf"; constexpr const char StartIm[] = "blocked_startim"; constexpr const char Teleport[] = "blocked_teleport"; diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index fd92632ec0..58cecd9b6e 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -901,10 +901,7 @@ void RlvHandler::setCameraOverride(bool fOverride) // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c void RlvHandler::onSitOrStand(bool fSitting) { - if (rlv_handler_t::isEnabled()) - { - RlvSettings::updateLoginLastLocation(); - } + RlvSettings::updateLoginLastLocation(); if ( (hasBehaviour(RLV_BHVR_STANDTP)) && (!fSitting) && (!m_posSitSource.isExactlyZero()) ) { @@ -916,6 +913,30 @@ void RlvHandler::onSitOrStand(bool fSitting) doOnIdleOneTime(boost::bind(RlvUtil::forceTp, m_posSitSource)); m_posSitSource.setZero(); } + else if ( (!fSitting) && (m_fPendingGroundSit) ) + { + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + send_agent_update(TRUE, TRUE); + + m_fPendingGroundSit = false; + m_idPendingSitActor = m_idPendingUnsitActor; + } + + if (isAgentAvatarValid()) + { + const LLViewerObject* pSitObj = static_cast(gAgentAvatarp->getParent()); + const LLUUID& idSitObj = (pSitObj) ? pSitObj->getID() : LLUUID::null; + if (fSitting) + { + RlvBehaviourNotifyHandler::instance().onSit(idSitObj, !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SIT, m_idPendingSitActor)); + m_idPendingSitActor.setNull(); + } + else + { + RlvBehaviourNotifyHandler::instance().onStand(idSitObj, !gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, m_idPendingUnsitActor)); + m_idPendingUnsitActor.setNull(); + } + } } // Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a @@ -2118,6 +2139,8 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& { if (gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType())) { + LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID())); + Rlv::forceAtmosphericShadersIfAvailable(); // If we're not using deferred but are using Windlight shaders we need to force use of FBO and depthmap texture @@ -2131,8 +2154,13 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& gPipeline.resetVertexBuffers(); LLViewerShaderMgr::instance()->setShaders(); } - - LLVfxManager::instance().addEffect(new RlvSphereEffect(rlvCmd.getObjectID())); + else if (!gPipeline.mDeferredLight.isComplete()) + { + // In case of deferred with no shadows, no ambient occlusion, no depth of field, and no antialiasing + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + RLV_ASSERT(gPipeline.mDeferredLight.isComplete()); + } } else { @@ -2794,6 +2822,9 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const { gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); send_agent_update(TRUE, TRUE); // See behaviour notes on why we have to force an agent update here + + gRlvHandler.m_idPendingSitActor.setNull(); + gRlvHandler.m_idPendingUnsitActor = gRlvHandler.getCurrentObject(); } } break; @@ -3236,6 +3267,34 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCm return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; } +// Handles: @sitground=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + if ( (!RlvActions::canGroundSit(rlvCmd.getObjectID())) || (!isAgentAvatarValid()) ) + return RLV_RET_FAILED_LOCK; + + if (!gAgentAvatarp->isSitting()) + { + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + + gRlvHandler.m_fPendingGroundSit = false; + gRlvHandler.m_idPendingSitActor = gRlvHandler.getCurrentObject(); + gRlvHandler.m_idPendingUnsitActor.setNull(); + } + else if (gAgentAvatarp->getParent()) + { + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + + gRlvHandler.m_fPendingGroundSit = true; + gRlvHandler.m_idPendingSitActor.setNull(); + gRlvHandler.m_idPendingUnsitActor = gRlvHandler.getCurrentObject(); + } + send_agent_update(TRUE, TRUE); + + return RLV_RET_SUCCESS; +} + // Handles: @sit:=force template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) @@ -3247,10 +3306,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) LLViewerObject* pObj = NULL; if (idTarget.isNull()) { - if ( (!RlvActions::canGroundSit()) || ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting())) ) - return RLV_RET_FAILED_LOCK; - gAgent.sitDown(); - send_agent_update(TRUE, TRUE); + return RlvForceHandler::onCommand(rlvCmd); } else if ( ((pObj = gObjectList.findObject(idTarget)) != NULL) && (LL_PCODE_VOLUME == pObj->getPCode())) { @@ -3273,6 +3329,9 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObj->mID); gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); pObj->getRegion()->sendReliableMessage(); + + gRlvHandler.m_idPendingSitActor = gRlvHandler.getCurrentObject(); + gRlvHandler.m_idPendingUnsitActor.setNull(); } else { diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 01da4b6269..e5a6b0895e 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -266,6 +266,9 @@ protected: bool m_fCanCancelTp; // @accepttp=n and @tpto=force mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const) + bool m_fPendingGroundSit = false; // @sitground=force + LLUUID m_idPendingSitActor; // @sit=force and @sitground=force + LLUUID m_idPendingUnsitActor; // @unsit=force mutable LLUUID m_idAgentGroup; // @setgroup=n std::pair m_PendingGroupChange; // @setgroup=force std::pair m_GroupChangeExpiration; // @setgroup=force diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index f633d12770..e9bdaf893e 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -106,7 +106,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourInfo("detachthis_except", RLV_BHVR_DETACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE)); addEntry(new RlvBehaviourInfo("detachallthis_except", RLV_BHVR_DETACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); addEntry(new RlvBehaviourGenericToggleProcessor("edit")); + addEntry(new RlvBehaviourGenericProcessor("editattach", RLV_BHVR_EDITATTACH)); addEntry(new RlvBehaviourGenericProcessor("editobj", RLV_BHVR_EDITOBJ)); + addEntry(new RlvBehaviourGenericProcessor("editworld", RLV_BHVR_EDITWORLD)); addEntry(new RlvBehaviourGenericToggleProcessor("viewtransparent", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericToggleProcessor("viewwireframe", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor("emote", RLV_BHVR_EMOTE)); @@ -142,6 +144,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericToggleProcessor("setdebug")); addEntry(new RlvBehaviourGenericToggleProcessor("setenv")); addEntry(new RlvBehaviourGenericProcessor("setgroup", RLV_BHVR_SETGROUP)); + addEntry(new RlvBehaviourGenericProcessor("share", RLV_BHVR_SHARE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourInfo("sharedunwear", RLV_BHVR_SHAREDUNWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("sharedwear", RLV_BHVR_SHAREDWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourProcessor("showhovertext")); @@ -169,7 +172,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("temprun", RLV_BHVR_TEMPRUN)); addEntry(new RlvBehaviourGenericProcessor("touchall", RLV_BHVR_TOUCHALL)); addEntry(new RlvBehaviourGenericProcessor("touchattach", RLV_BHVR_TOUCHATTACH)); - addEntry(new RlvBehaviourGenericProcessor("touchattachother", RLV_BHVR_TOUCHATTACHOTHER)); + addEntry(new RlvBehaviourGenericProcessor("touchattachother", RLV_BHVR_TOUCHATTACHOTHER)); addEntry(new RlvBehaviourGenericProcessor("touchattachself", RLV_BHVR_TOUCHATTACHSELF)); addEntry(new RlvBehaviourGenericProcessor("touchfar", RLV_BHVR_FARTOUCH, RlvBehaviourInfo::BHVR_SYNONYM)); addEntry(new RlvBehaviourGenericProcessor("touchhud", RLV_BHVR_TOUCHHUD, RlvBehaviourInfo::BHVR_EXTENDED)); @@ -293,6 +296,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvForceProcessor("setcam_mode", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("setgroup")); addEntry(new RlvForceProcessor("sit")); + addEntry(new RlvForceProcessor("sitground")); addEntry(new RlvForceProcessor("tpto")); addEntry(new RlvBehaviourInfo("unsit", RLV_BHVR_UNSIT, RLV_TYPE_FORCE)); @@ -1927,6 +1931,22 @@ void RlvBehaviourNotifyHandler::onReattach(const LLViewerJointAttachment* pAttac sendNotification(llformat("reattached %s %s", (fAllowed) ? "legally" : "illegally", pAttachPt->getName().c_str())); } +void RlvBehaviourNotifyHandler::onSit(const LLUUID& idObj, bool fAllowed) +{ + if (idObj.isNull()) + sendNotification(llformat("sat ground %s", (fAllowed) ? "legally" : "illegally")); + else + sendNotification(llformat("sat object %s %s", (fAllowed) ? "legally" : "illegally", idObj.asString().c_str())); +} + +void RlvBehaviourNotifyHandler::onStand(const LLUUID& idObj, bool fAllowed) +{ + if (idObj.isNull()) + sendNotification(llformat("unsat ground %s", (fAllowed) ? "legally" : "illegally")); + else + sendNotification(llformat("unsat object %s %s", (fAllowed) ? "legally" : "illegally", idObj.asString().c_str())); +} + // ========================================================================= // Various helper classes/timers/functors // diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index c36cde75b0..d20ba1790b 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -625,11 +625,13 @@ public: * 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); + 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); + void onSit(const LLUUID& idObj, bool fAllowed); + void onStand(const LLUUID& idObj, bool fAllowed); protected: void onCommand(const RlvCommand& rlvCmd, ERlvCmdRet eRet, bool fInternal); diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml index de0e99d6d0..3ffb3d9009 100644 --- a/indra/newview/skins/default/xui/en/rlva_strings.xml +++ b/indra/newview/skins/default/xui/en/rlva_strings.xml @@ -141,6 +141,16 @@ value Unable to show script dialog or textbox due to RLV restrictions + blocked_share + + value + Unable to share inventory with [RECIPIENT] due to RLV restrictions. + + blocked_share_generic + + value + Unable to share inventory due to RLV restrictions. + blocked_startim value