diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 96028e3f8f4646bc87633d18c02004b01cbad02d..1a9202ec909703112a75ef6258529b24644a6585 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -695,6 +695,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] + LLSD key; LLFloaterSidePanelContainer::showPanel("inventory", key); LLFloaterReg::showInstance("im_container"); @@ -913,10 +921,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<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL) +// static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL) +// [RLVa:KB] - @share + static void give_inventory(uuid_vec_t avatar_uuids, std::vector<LLAvatarName> 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<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel); if (inventory_selected_uuids.empty()) { @@ -1039,6 +1071,14 @@ std::set<LLUUID> 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 a59262180a05c18f758f82e8b63e451fc2834c81..c0306c2c145c353a0b3fe096ed0a7fad57f53744 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" @@ -200,7 +201,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 { @@ -361,6 +365,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()); @@ -394,11 +406,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); @@ -451,6 +476,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent, { LLRecentPeople::instance().add(to_agent); } + return true; // [/RLVa:KB] } @@ -466,6 +492,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; @@ -513,6 +547,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 20e6df76e5c7add2d46fade4f917b319e522e43a..86919f90104fe674e03143f01f914412c31edc03 100644 --- a/indra/newview/llgiveinventory.h +++ b/indra/newview/llgiveinventory.h @@ -82,9 +82,14 @@ class LLGiveInventory 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 d4f3ba4773f47e3b7b80975408dd1c81f8172d2e..083b4a98ddb9b96088a2757a6f5b2894f30b9df0 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 6a17c84be815d831eea0264258279abda21c74d2..2dee36662f15c22f0902f5d77573f8a25974bdd6 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -6043,6 +6043,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 f7216bab71cfbf524cbf12c231dfb5f35382e487..8f63c59f81cfc74a9365b86ae5129ba0449c258e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -4367,8 +4367,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 806fd523c6d52db0fd9cb622170809ae9a5e3279..476480aa8bac0e11ff966a010d24ea067f1151e3 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] @@ -1652,6 +1653,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) { @@ -2476,6 +2485,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 ); @@ -2502,6 +2517,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); @@ -2515,6 +2536,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 afdd79811d65328c70fce33335b3eb0db758336d..b57d03292f4947b7012e0d77d8b394105b21e69f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3051,17 +3051,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 583fbf813c533bb58ec6ce7dfdccea980aac1fd1..bffe8301232a8b41d0f62d2bb47b40428c2173fe 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -975,7 +975,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mScratchBuffer.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 099539d68a9d679ef4c844ebfa6f96bb9b9a2177..43ba16276cb0fa70662a6fe663eb167a40890346 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) { @@ -386,6 +401,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 // @@ -408,19 +428,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 @@ -467,6 +521,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: @@ -520,8 +580,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) @@ -539,7 +599,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; @@ -552,12 +612,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 object - test for (1.c) and (1.h) + fCanTouch = + ( (!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()) { - // Rezzed or attachment worn by other - test for (1.c), (2.d), (2.e) and (1/2.h) + // Attachment worn by other - test for (2.d), (2.e) and (2.h) + const LLUUID& idAttachAgent = static_cast<LLViewerObject*>(pObj->getRoot())->getID(); 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_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 99f94df7cd3a14df164062de7bb3e694ea71a887..ea341f784e83782af9ccff5f3f3791e5a47f694d 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -35,6 +35,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 { // ====== @@ -91,6 +93,16 @@ class RlvActions */ 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) */ @@ -226,6 +238,10 @@ class RlvActions */ static bool canChangeEnvironment(const LLUUID& idRlvObject = LLUUID::null); + /* + * Returns true if a postprocessing shader is currently active + */ + static bool hasPostProcess(); // ================= // World interaction @@ -247,6 +263,11 @@ class RlvActions */ 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) */ @@ -256,6 +277,7 @@ class RlvActions * 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 df7ebb5c1acf7324d8d4468f6a597ba1de297074..a0985de0b17afb97feb536ea4d54df30a4073c98 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -127,6 +127,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" @@ -154,7 +155,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" @@ -174,6 +177,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" @@ -431,6 +435,8 @@ namespace RlvStringKeys inline constexpr std::string_view RecvIm = "blocked_recvim"sv; inline constexpr std::string_view RecvImRemote = "blocked_recvim_remote"sv; inline constexpr std::string_view SendIm = "blocked_sendim"sv; + inline constexpr std::string_view Share = make_string_view("blocked_share"); + inline constexpr std::string_view ShareGeneric = make_string_view("blocked_share_generic"); inline constexpr std::string_view StartConference = "blocked_startconf"sv; inline constexpr std::string_view StartIm = "blocked_startim"sv; inline constexpr std::string_view Teleport = "blocked_teleport"sv; diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index a03d72b41f421a8d94b9c92aa3e2506cd8b53754..6dc05f8f1ce7813e5230423712dce75d692128b0 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -888,10 +888,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()) ) { @@ -903,6 +900,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<const LLViewerObject*>(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 @@ -2104,6 +2125,8 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::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 @@ -2117,8 +2140,13 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SETSPHERE>::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 { @@ -2736,6 +2764,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; @@ -3178,6 +3209,34 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCm return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; } +// Handles: @sitground=force +template<> template<> +ERlvCmdRet RlvForceHandler<RLV_BHVR_SITGROUND>::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:<uuid>=force template<> template<> ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd) @@ -3189,10 +3248,7 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::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<RLV_BHVR_SITGROUND>::onCommand(rlvCmd); } else if ( ((pObj = gObjectList.findObject(idTarget)) != NULL) && (LL_PCODE_VOLUME == pObj->getPCode())) { @@ -3215,6 +3271,9 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::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 edd495faed5225fb2e327cd26c96240cc3921662..09adc36d07166efa0b7ba28a83574fdf2190be95 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -267,6 +267,9 @@ class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGrou 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<LLUUID, std::string> m_PendingGroupChange; // @setgroup=force std::pair<LLTimer, LLUUID> m_GroupChangeExpiration; // @setgroup=force diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 12cf12d5e953e74f9694a6cf0d5b51b52e13bfbd..6f1e5819505aade063538c71847d56e4fb045845 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -102,7 +102,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<RLV_BHVR_EDIT, RLV_OPTION_NONE_OR_EXCEPTION>("edit")); + addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("editattach", RLV_BHVR_EDITATTACH)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("editobj", RLV_BHVR_EDITOBJ)); + addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("editworld", RLV_BHVR_EDITWORLD)); addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWTRANSPARENT, RLV_OPTION_NONE>("viewtransparent", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_VIEWWIREFRAME, RLV_OPTION_NONE>("viewwireframe", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("emote", RLV_BHVR_EMOTE)); @@ -138,6 +140,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug")); addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv")); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP)); + addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("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<RLV_BHVR_SHOWHOVERTEXT>("showhovertext")); @@ -165,7 +168,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("temprun", RLV_BHVR_TEMPRUN)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchall", RLV_BHVR_TOUCHALL)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchattach", RLV_BHVR_TOUCHATTACH)); - addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchattachother", RLV_BHVR_TOUCHATTACHOTHER)); + addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchattachother", RLV_BHVR_TOUCHATTACHOTHER)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchattachself", RLV_BHVR_TOUCHATTACHSELF)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("touchfar", RLV_BHVR_FARTOUCH, RlvBehaviourInfo::BHVR_SYNONYM)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("touchhud", RLV_BHVR_TOUCHHUD, RlvBehaviourInfo::BHVR_EXTENDED)); @@ -289,6 +292,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_MODE>("setcam_mode", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor<RLV_BHVR_SETGROUP>("setgroup")); addEntry(new RlvForceProcessor<RLV_BHVR_SIT>("sit")); + addEntry(new RlvForceProcessor<RLV_BHVR_SITGROUND>("sitground")); addEntry(new RlvForceProcessor<RLV_BHVR_TPTO>("tpto")); addEntry(new RlvBehaviourInfo("unsit", RLV_BHVR_UNSIT, RLV_TYPE_FORCE)); @@ -1919,6 +1923,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 398af45d4d7e5e936342c605f5b65a24f3568519..a8696bc01abadb4bf5a7cab910df6bba1da5da1b 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -630,11 +630,13 @@ class RlvBehaviourNotifyHandler final : public LLSingleton<RlvBehaviourNotifyHan * 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 de0e99d6d0949a6a1dec9013a380b5477fca062d..3ffb3d90094faa6b79b16e959a6ecb84b45d39a9 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 @@ <key>value</key> <string>Unable to show script dialog or textbox due to RLV restrictions</string> </map> + <key>blocked_share</key> + <map> + <key>value</key> + <string>Unable to share inventory with [RECIPIENT] due to RLV restrictions.</string> + </map> + <key>blocked_share_generic</key> + <map> + <key>value</key> + <string>Unable to share inventory due to RLV restrictions.</string> + </map> <key>blocked_startim</key> <map> <key>value</key>