diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index f41fce8ed..07aa44db3 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -1098,3 +1098,9 @@ LLPermissions ll_permissions_from_sd(const LLSD& sd_perm) rv.fix(); return rv; } + +bool LLPermissions::allowExportBy(LLUUID const& requester, bool supports_export) const +{ + return !mIsGroupOwned && requester == mOwner && (requester == mCreator || (supports_export && (mMaskEveryone & PERM_EXPORT))); +} + diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 7d3a68d35..d4f736dc3 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -275,6 +275,13 @@ public: inline bool allowCopyBy(const LLUUID& agent_id, const LLUUID& group) const; inline bool allowMoveBy(const LLUUID &agent_id, const LLUUID &group) const; + // Returns true if export is allowed. + // If a grid supports PERM_EXPORT then they should also check if (any) element + // has that bit set and allow exporting even when this function returns false, + // or pass supports_export as true, which causes to perform that check using + // these permissions. + bool allowExportBy(LLUUID const& requester, bool supports_export = false) const; + // This somewhat specialized function is meant for testing if the // current owner is allowed to transfer to the specified agent id. inline bool allowTransferTo(const LLUUID &agent_id) const; diff --git a/indra/newview/awavefront.cpp b/indra/newview/awavefront.cpp index 3f4d2c994..635d9b9a9 100644 --- a/indra/newview/awavefront.cpp +++ b/indra/newview/awavefront.cpp @@ -220,16 +220,13 @@ void WavefrontSaver::Add(const LLViewerObject* some_vo) } namespace { + // Identical to the one in daeexport.cpp. bool can_export_node(const LLSelectNode* node) { - if (const LLPermissions* perms = node->mPermissions) - { - if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) - { - return true; - } - } - return false; + LLPermissions* perms = node->mPermissions; // Is perms ever NULL? + // This tests the PERM_EXPORT bit too, which is not really necessary (just checking if it's set + // on the root prim would suffice), but also isn't hurting. + return perms && perms->allowExportBy(gAgentID, LFSimFeatureHandler::instance().simSupportsExport()); } class LFSaveSelectedObjects : public view_listener_t { diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp index 586dc8cf5..f37a6e5a5 100644 --- a/indra/newview/daeexport.cpp +++ b/indra/newview/daeexport.cpp @@ -117,16 +117,13 @@ namespace DAEExportUtil } } - bool canExportNode(const LLSelectNode* node) + // Identical to the one in awavefront.cpp + bool can_export_node(const LLSelectNode* node) { - if (const LLPermissions* perms = node->mPermissions) - { - if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) - { - return true; - } - } - return false; + LLPermissions* perms = node->mPermissions; // Is perms ever NULL? + // This tests the PERM_EXPORT bit too, which is not really necessary (just checking if it's set + // on the root prim would suffice), but also isn't hurting. + return perms && perms->allowExportBy(gAgentID, LFSimFeatureHandler::instance().simSupportsExport()); } void saveSelectedObject() @@ -144,7 +141,7 @@ namespace DAEExportUtil { total++; LLSelectNode* node = *iter; - if (!canExportNode(node) || !node->getObject()->getVolume()) continue; + if (!can_export_node(node) || !node->getObject()->getVolume()) continue; included++; daesaver->Add(node->getObject(), node->mName); } diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index c2d3c549b..81d807259 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -26,6 +26,7 @@ #include "llviewerprecompiledheaders.h" +#include "lfsimfeaturehandler.h" #include "llpaneleditwearable.h" #include "llpanel.h" #include "llviewerwearable.h" @@ -1422,11 +1423,8 @@ bool LLPanelEditWearable::updatePermissions() // Exporting (of slider values) is allowed when the wearable is full perm, and owned by and created by the user. // Of course, only modifiable is enough for the user to write down the values and enter them else where... but why make it easy for them to break the ToS. - if (is_complete && - gAgent.getID() == item->getPermissions().getOwner() && - gAgent.getID() == item->getPermissions().getCreator() && - (PERM_ITEM_UNRESTRICTED & - perm_mask) == PERM_ITEM_UNRESTRICTED) + if (is_complete && + (item->getPermissions().allowExportBy(gAgent.getID(), LFSimFeatureHandler::instance().simSupportsExport()))) { can_export = true; } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 9f3414448..fa7f0565c 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1177,7 +1177,7 @@ void LLPanelPermissions::onCommitEveryoneCopy(LLUICtrl *ctrl, void *data) void LLPanelPermissions::onCommitExport(const LLSD& param) { - LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param, PERM_EXPORT); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param.asBoolean(), PERM_EXPORT); } // static diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 21d4226a6..0031f2a87 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -54,6 +54,7 @@ #include "llappearancemgr.h" #include "llagentwearables.h" #include "jcfloaterareasearch.h" +#include "lfsimfeaturehandler.h" #include "llagentpilot.h" #include "llcompilequeue.h" @@ -2884,30 +2885,22 @@ class LLObjectEnableExport : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = !!LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if (new_value) + LLPermissions perms; + bool new_value = LLSelectMgr::getInstance()->selectGetPermissions(perms) && perms.isOwned(); // At least one object, accumulated permissions of all objects. + bool supports_export = LFSimFeatureHandler::instance().simSupportsExport(); + if (new_value && !(supports_export && (perms.getMaskEveryone() & PERM_EXPORT))) // No need to call allowExportBy if PERM_EXPORT is set on (all) root objects. { struct ff : public LLSelectedNodeFunctor { - ff(const LLSD& data) : LLSelectedNodeFunctor(), userdata(data) - { - } - const LLSD& userdata; + bool mSupportsExport; + ff(bool supports_export) : mSupportsExport(supports_export) { } virtual bool apply(LLSelectNode* node) { - // Note: the actual permission checking algorithm depends on the grid TOS and must be - // performed for each prim and texture. This is done later in llviewerobjectbackup.cpp. - // This means that even if the item is enabled in the menu, the export may fail should - // the permissions not be met for each exported asset. The permissions check below - // therefore only corresponds to the minimal permissions requirement common to all grids. - LLPermissions *item_permissions = node->mPermissions; - return (gAgent.getID() == item_permissions->getOwner() && - (gAgent.getID() == item_permissions->getCreator() || - (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)); + return node->mPermissions->allowExportBy(gAgent.getID(), mSupportsExport); } }; - ff * the_ff = new ff(userdata); - new_value = LLSelectMgr::getInstance()->getSelection()->applyToNodes(the_ff, false); + ff the_ff(supports_export); + new_value = LLSelectMgr::getInstance()->getSelection()->applyToNodes(&the_ff, false); } gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index 09783ed21..795426a2d 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -79,6 +79,7 @@ #include "llviewerwindow.h" #include "hippogridmanager.h" +#include "lfsimfeaturehandler.h" #include "llviewerobjectbackup.h" @@ -398,18 +399,7 @@ void LLObjectBackup::exportObject_continued(AIFilePicker* filepicker) bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) { - if (gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - // In Second Life, you must be the creator to be permitted to export the asset. - return (gAgent.getID() == item_permissions->getOwner() && - gAgent.getID() == item_permissions->getCreator()); - } - else - { - // Out of Second Life, simply check that the asset is full perms. - return (gAgent.getID() == item_permissions->getOwner() && - (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - } + return item_permissions->allowExportBy(gAgent.getID(), LFSimFeatureHandler::instance().simSupportsExport()); } // So far, only Second Life forces TPVs to verify the creator for textures...