diff options
Diffstat (limited to 'indra/llinventory')
38 files changed, 8112 insertions, 8112 deletions
diff --git a/indra/llinventory/llcategory.cpp b/indra/llinventory/llcategory.cpp index 97a496845b..26b3ee76c2 100644 --- a/indra/llinventory/llcategory.cpp +++ b/indra/llinventory/llcategory.cpp @@ -1,24 +1,24 @@ -/** +/** * @file llcategory.cpp * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -46,27 +46,27 @@ const LLCategory LLCategory::none; // in CATEGORY_NAME[1]. const S32 CATEGORY_INDEX[] = { - 1, // ROOT - 6, // object - 7, // clothing - 7, // texture - 7, // sound - 7, // landmark - 7, // object|component - 7, // off the end (required for child count calculations) + 1, // ROOT + 6, // object + 7, // clothing + 7, // texture + 7, // sound + 7, // landmark + 7, // object|component + 7, // off the end (required for child count calculations) }; // The heap of names const char* CATEGORY_NAME[] = { - "(none)", - "Object", // (none) - "Clothing", - "Texture", - "Sound", - "Landmark", - "Component", // object - NULL + "(none)", + "Object", // (none) + "Clothing", + "Texture", + "Sound", + "Landmark", + "Component", // object + NULL }; ///---------------------------------------------------------------------------- @@ -75,49 +75,49 @@ const char* CATEGORY_NAME[] = LLCategory::LLCategory() { - // this is used as a simple compile time assertion. If this code - // fails to compile, the depth has been changed, and we need to - // clean up some of the code that relies on the depth, such as the - // default constructor. If CATEGORY_DEPTH != 4, this code will - // attempt to construct a zero length array - which the compiler - // should balk at. -// static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '}; // unused - - // actually initialize the object. - mData[0] = 0; - mData[1] = 0; - mData[2] = 0; - mData[3] = 0; + // this is used as a simple compile time assertion. If this code + // fails to compile, the depth has been changed, and we need to + // clean up some of the code that relies on the depth, such as the + // default constructor. If CATEGORY_DEPTH != 4, this code will + // attempt to construct a zero length array - which the compiler + // should balk at. +// static const char CATEGORY_DEPTH_CHECK[(CATEGORY_DEPTH == 4)?1:0] = {' '}; // unused + + // actually initialize the object. + mData[0] = 0; + mData[1] = 0; + mData[2] = 0; + mData[3] = 0; } void LLCategory::init(U32 value) { - U8 v; - for(S32 i = 0; i < CATEGORY_DEPTH; i++) - { - v = (U8)((0x000000ff) & value); - mData[CATEGORY_DEPTH - 1 - i] = v; - value >>= 8; - } + U8 v; + for(S32 i = 0; i < CATEGORY_DEPTH; i++) + { + v = (U8)((0x000000ff) & value); + mData[CATEGORY_DEPTH - 1 - i] = v; + value >>= 8; + } } U32 LLCategory::getU32() const { - U32 rv = 0; - rv |= mData[0]; - rv <<= 8; - rv |= mData[1]; - rv <<= 8; - rv |= mData[2]; - rv <<= 8; - rv |= mData[3]; - return rv; + U32 rv = 0; + rv |= mData[0]; + rv <<= 8; + rv |= mData[1]; + rv <<= 8; + rv |= mData[2]; + rv <<= 8; + rv |= mData[3]; + return rv; } S32 LLCategory::getSubCategoryCount() const { - S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]]; - return rv; + S32 rv = CATEGORY_INDEX[mData[0] + 1] - CATEGORY_INDEX[mData[0]]; + return rv; } // This method will return a category that is the nth subcategory. If @@ -125,53 +125,53 @@ S32 LLCategory::getSubCategoryCount() const // return a copy of this. LLCategory LLCategory::getSubCategory(U8 n) const { - LLCategory rv(*this); - for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++) - { - if(rv.mData[i] == 0) - { - rv.mData[i] = n + 1; - break; - } - } - return rv; + LLCategory rv(*this); + for(S32 i = 0; i < (CATEGORY_DEPTH - 1); i++) + { + if(rv.mData[i] == 0) + { + rv.mData[i] = n + 1; + break; + } + } + return rv; } // This method will return the name of the leaf category type const char* LLCategory::lookupName() const { - S32 i = 0; - S32 index = mData[i++]; - while((i < CATEGORY_DEPTH) && (mData[i] != 0)) - { - index = CATEGORY_INDEX[index]; - ++i; - } - return CATEGORY_NAME[index]; + S32 i = 0; + S32 index = mData[i++]; + while((i < CATEGORY_DEPTH) && (mData[i] != 0)) + { + index = CATEGORY_INDEX[index]; + ++i; + } + return CATEGORY_NAME[index]; } // message serialization void LLCategory::packMessage(LLMessageSystem* msg) const { - U32 data = getU32(); - msg->addU32Fast(_PREHASH_Category, data); + U32 data = getU32(); + msg->addU32Fast(_PREHASH_Category, data); } // message serialization void LLCategory::unpackMessage(LLMessageSystem* msg, const char* block) { - U32 data; - msg->getU32Fast(block, _PREHASH_Category, data); - init(data); + U32 data; + msg->getU32Fast(block, _PREHASH_Category, data); + init(data); } // message serialization void LLCategory::unpackMultiMessage(LLMessageSystem* msg, const char* block, - S32 block_num) + S32 block_num) { - U32 data; - msg->getU32Fast(block, _PREHASH_Category, data, block_num); - init(data); + U32 data; + msg->getU32Fast(block, _PREHASH_Category, data, block_num); + init(data); } ///---------------------------------------------------------------------------- diff --git a/indra/llinventory/llcategory.h b/indra/llinventory/llcategory.h index 390a8a1f1e..a68ebaf721 100644 --- a/indra/llinventory/llcategory.h +++ b/indra/llinventory/llcategory.h @@ -1,25 +1,25 @@ -/** +/** * @file llcategory.h * @brief LLCategory class header file. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,11 +40,11 @@ // To output the names of all top level categories, you could do the // following: // -// S32 count = LLCategory::none.getSubCategoryCount(); -// for(S32 i = 0; i < count; i++) -// { -// LL_INFOS() << none.getSubCategory(i).lookupNmae() << LL_ENDL; -// } +// S32 count = LLCategory::none.getSubCategoryCount(); +// for(S32 i = 0; i < count; i++) +// { +// LL_INFOS() << none.getSubCategory(i).lookupNmae() << LL_ENDL; +// } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLMessageSystem; @@ -52,46 +52,46 @@ class LLMessageSystem; class LLCategory { public: - // Nice default static const. - static const LLCategory none; + // Nice default static const. + static const LLCategory none; - // construction. Since this is really a POD type, destruction, - // copy, and assignment are handled by the compiler. - LLCategory(); - explicit LLCategory(U32 value) { init(value); } + // construction. Since this is really a POD type, destruction, + // copy, and assignment are handled by the compiler. + LLCategory(); + explicit LLCategory(U32 value) { init(value); } - // methods - void init(U32 value); - U32 getU32() const; - S32 getSubCategoryCount() const; + // methods + void init(U32 value); + U32 getU32() const; + S32 getSubCategoryCount() const; - // This method will return a category that is the nth - // subcategory. If you're already at the bottom of the hierarchy, - // then the method will return a copy of this. - LLCategory getSubCategory(U8 n) const; + // This method will return a category that is the nth + // subcategory. If you're already at the bottom of the hierarchy, + // then the method will return a copy of this. + LLCategory getSubCategory(U8 n) const; - // This method will return the name of the leaf category type - const char* lookupName() const; + // This method will return the name of the leaf category type + const char* lookupName() const; - // This method will return the full hierarchy name in an easily - // interpreted (TOP)|(SUB1)|(SUB2) format. *NOTE: not implemented - // because we don't have anything but top level categories at the - // moment. - //const char* lookupFullName() const; + // This method will return the full hierarchy name in an easily + // interpreted (TOP)|(SUB1)|(SUB2) format. *NOTE: not implemented + // because we don't have anything but top level categories at the + // moment. + //const char* lookupFullName() const; - // message serialization - void packMessage(LLMessageSystem* msg) const; - void unpackMessage(LLMessageSystem* msg, const char* block); - void unpackMultiMessage(LLMessageSystem* msg, const char* block, - S32 block_num); + // message serialization + void packMessage(LLMessageSystem* msg) const; + void unpackMessage(LLMessageSystem* msg, const char* block); + void unpackMultiMessage(LLMessageSystem* msg, const char* block, + S32 block_num); protected: - enum - { - CATEGORY_TOP = 0, - CATEGORY_DEPTH = 4, - }; + enum + { + CATEGORY_TOP = 0, + CATEGORY_DEPTH = 4, + }; - U8 mData[CATEGORY_DEPTH]; + U8 mData[CATEGORY_DEPTH]; }; diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index cd32152adc..6bd0f8df53 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -1,222 +1,222 @@ -/** - * @file llfoldertype.cpp - * @brief Implementatino of LLFolderType functionality. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llfoldertype.h" -#include "lldictionary.h" -#include "llmemory.h" -#include "llsingleton.h" - -///---------------------------------------------------------------------------- -/// Class LLFolderType -///---------------------------------------------------------------------------- -struct FolderEntry : public LLDictionaryEntry -{ - FolderEntry(const std::string &type_name, // 8 character limit! - bool is_protected, // can the viewer change categories of this type? - bool is_automatic, // always made before first login? - bool is_singleton // should exist as a unique copy under root - ) - : - LLDictionaryEntry(type_name), - mIsProtected(is_protected), - mIsAutomatic(is_automatic), - mIsSingleton(is_singleton) - { - llassert(type_name.length() <= 8); - } - - const bool mIsProtected; - const bool mIsAutomatic; - const bool mIsSingleton; -}; - -class LLFolderDictionary : public LLSingleton<LLFolderDictionary>, - public LLDictionary<LLFolderType::EType, FolderEntry> -{ - LLSINGLETON(LLFolderDictionary); -protected: - virtual LLFolderType::EType notFound() const override - { - return LLFolderType::FT_NONE; - } -}; - -// Folder types -// -// PROTECTED means that folders of this type can't be moved, deleted -// or otherwise modified by the viewer. -// -// SINGLETON means that there should always be exactly one folder of -// this type, and it should be the root or a child of the root. This -// is true for most types of folders. -// -// AUTOMATIC means that a copy of this folder should be created under -// the root before the user ever logs in, and should never be created -// from the viewer. A missing AUTOMATIC folder should be treated as a -// fatal error by the viewer, since it indicates either corrupted -// inventory or a failure in the inventory services. -// -LLFolderDictionary::LLFolderDictionary() -{ - // TYPE NAME, PROTECTED, AUTOMATIC, SINGLETON - addEntry(LLFolderType::FT_TEXTURE, new FolderEntry("texture", true, true, true)); - addEntry(LLFolderType::FT_SOUND, new FolderEntry("sound", true, true, true)); - addEntry(LLFolderType::FT_CALLINGCARD, new FolderEntry("callcard", true, true, false)); - addEntry(LLFolderType::FT_LANDMARK, new FolderEntry("landmark", true, false, false)); - addEntry(LLFolderType::FT_CLOTHING, new FolderEntry("clothing", true, true, true)); - addEntry(LLFolderType::FT_OBJECT, new FolderEntry("object", true, true, true)); - addEntry(LLFolderType::FT_NOTECARD, new FolderEntry("notecard", true, true, true)); - addEntry(LLFolderType::FT_ROOT_INVENTORY, new FolderEntry("root_inv", true, true, true)); - addEntry(LLFolderType::FT_LSL_TEXT, new FolderEntry("lsltext", true, true, true)); - addEntry(LLFolderType::FT_BODYPART, new FolderEntry("bodypart", true, true, true)); - addEntry(LLFolderType::FT_TRASH, new FolderEntry("trash", true, false, true)); - addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new FolderEntry("snapshot", true, true, true)); - addEntry(LLFolderType::FT_LOST_AND_FOUND, new FolderEntry("lstndfnd", true, true, true)); - addEntry(LLFolderType::FT_ANIMATION, new FolderEntry("animatn", true, true, true)); - addEntry(LLFolderType::FT_GESTURE, new FolderEntry("gesture", true, true, true)); - addEntry(LLFolderType::FT_FAVORITE, new FolderEntry("favorite", true, false, true)); - - for (S32 ensemble_num = S32(LLFolderType::FT_ENSEMBLE_START); ensemble_num <= S32(LLFolderType::FT_ENSEMBLE_END); ensemble_num++) - { - addEntry(LLFolderType::EType(ensemble_num), new FolderEntry("ensemble", false, false, false)); // Not used - } - - addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", true, false, true)); - addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", false, false, false)); - addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", true, false, true)); - - addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", true, false, false)); // Not used? - - addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", true, false, true)); - addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", true, false, false)); - - addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", true, false, false)); - - addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", false, false, false)); - addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", false, false, false)); - addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", false, false, false)); - - addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", true, false, true)); - addEntry(LLFolderType::FT_MATERIAL, new FolderEntry("material", true, false, true)); - - addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", false, false, false)); -}; - -// static -LLFolderType::EType LLFolderType::lookup(const std::string& name) -{ - return LLFolderDictionary::getInstance()->lookup(name); -} - -// static -const std::string &LLFolderType::lookup(LLFolderType::EType folder_type) -{ - const FolderEntry *entry = LLFolderDictionary::getInstance()->lookup(folder_type); - if (entry) - { - return entry->mName; - } - else - { - return badLookup(); - } -} - -// static -// Only plain folders and a few other types aren't protected. "Protected" means -// you can't move, deleted, or change certain properties such as their type. -bool LLFolderType::lookupIsProtectedType(EType folder_type) -{ - const LLFolderDictionary *dict = LLFolderDictionary::getInstance(); - const FolderEntry *entry = dict->lookup(folder_type); - if (entry) - { - return entry->mIsProtected; - } - return true; -} - -// static -// Is this folder type automatically created outside the viewer? -bool LLFolderType::lookupIsAutomaticType(EType folder_type) -{ - const LLFolderDictionary *dict = LLFolderDictionary::getInstance(); - const FolderEntry *entry = dict->lookup(folder_type); - if (entry) - { - return entry->mIsAutomatic; - } - return true; -} - -// static -// Should this folder always exist as a single copy under (or as) the root? -bool LLFolderType::lookupIsSingletonType(EType folder_type) -{ - const LLFolderDictionary *dict = LLFolderDictionary::getInstance(); - const FolderEntry *entry = dict->lookup(folder_type); - if (entry) - { - return entry->mIsSingleton; - } - return true; -} - -// static -bool LLFolderType::lookupIsEnsembleType(EType folder_type) -{ - return (folder_type >= FT_ENSEMBLE_START && - folder_type <= FT_ENSEMBLE_END); -} - -// static -LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type) -{ - if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP) - { - LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL; - } - return (LLAssetType::EType)folder_type; -} - -// static -LLFolderType::EType LLFolderType::assetTypeToFolderType(LLAssetType::EType asset_type) -{ - if (LLFolderType::lookup(LLFolderType::EType(asset_type)) == LLFolderType::badLookup()) - { - LL_WARNS() << "Converting to unknown folder type " << asset_type << LL_ENDL; - } - return (LLFolderType::EType)asset_type; -} - -// static -const std::string &LLFolderType::badLookup() -{ - static const std::string sBadLookup = "llfoldertype_bad_lookup"; - return sBadLookup; -} +/**
+ * @file llfoldertype.cpp
+ * @brief Implementatino of LLFolderType functionality.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfoldertype.h"
+#include "lldictionary.h"
+#include "llmemory.h"
+#include "llsingleton.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFolderType
+///----------------------------------------------------------------------------
+struct FolderEntry : public LLDictionaryEntry
+{
+ FolderEntry(const std::string &type_name, // 8 character limit!
+ bool is_protected, // can the viewer change categories of this type?
+ bool is_automatic, // always made before first login?
+ bool is_singleton // should exist as a unique copy under root
+ )
+ :
+ LLDictionaryEntry(type_name),
+ mIsProtected(is_protected),
+ mIsAutomatic(is_automatic),
+ mIsSingleton(is_singleton)
+ {
+ llassert(type_name.length() <= 8);
+ }
+
+ const bool mIsProtected;
+ const bool mIsAutomatic;
+ const bool mIsSingleton;
+};
+
+class LLFolderDictionary : public LLSingleton<LLFolderDictionary>,
+ public LLDictionary<LLFolderType::EType, FolderEntry>
+{
+ LLSINGLETON(LLFolderDictionary);
+protected:
+ virtual LLFolderType::EType notFound() const override
+ {
+ return LLFolderType::FT_NONE;
+ }
+};
+
+// Folder types
+//
+// PROTECTED means that folders of this type can't be moved, deleted
+// or otherwise modified by the viewer.
+//
+// SINGLETON means that there should always be exactly one folder of
+// this type, and it should be the root or a child of the root. This
+// is true for most types of folders.
+//
+// AUTOMATIC means that a copy of this folder should be created under
+// the root before the user ever logs in, and should never be created
+// from the viewer. A missing AUTOMATIC folder should be treated as a
+// fatal error by the viewer, since it indicates either corrupted
+// inventory or a failure in the inventory services.
+//
+LLFolderDictionary::LLFolderDictionary()
+{
+ // TYPE NAME, PROTECTED, AUTOMATIC, SINGLETON
+ addEntry(LLFolderType::FT_TEXTURE, new FolderEntry("texture", true, true, true));
+ addEntry(LLFolderType::FT_SOUND, new FolderEntry("sound", true, true, true));
+ addEntry(LLFolderType::FT_CALLINGCARD, new FolderEntry("callcard", true, true, false));
+ addEntry(LLFolderType::FT_LANDMARK, new FolderEntry("landmark", true, false, false));
+ addEntry(LLFolderType::FT_CLOTHING, new FolderEntry("clothing", true, true, true));
+ addEntry(LLFolderType::FT_OBJECT, new FolderEntry("object", true, true, true));
+ addEntry(LLFolderType::FT_NOTECARD, new FolderEntry("notecard", true, true, true));
+ addEntry(LLFolderType::FT_ROOT_INVENTORY, new FolderEntry("root_inv", true, true, true));
+ addEntry(LLFolderType::FT_LSL_TEXT, new FolderEntry("lsltext", true, true, true));
+ addEntry(LLFolderType::FT_BODYPART, new FolderEntry("bodypart", true, true, true));
+ addEntry(LLFolderType::FT_TRASH, new FolderEntry("trash", true, false, true));
+ addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, new FolderEntry("snapshot", true, true, true));
+ addEntry(LLFolderType::FT_LOST_AND_FOUND, new FolderEntry("lstndfnd", true, true, true));
+ addEntry(LLFolderType::FT_ANIMATION, new FolderEntry("animatn", true, true, true));
+ addEntry(LLFolderType::FT_GESTURE, new FolderEntry("gesture", true, true, true));
+ addEntry(LLFolderType::FT_FAVORITE, new FolderEntry("favorite", true, false, true));
+
+ for (S32 ensemble_num = S32(LLFolderType::FT_ENSEMBLE_START); ensemble_num <= S32(LLFolderType::FT_ENSEMBLE_END); ensemble_num++)
+ {
+ addEntry(LLFolderType::EType(ensemble_num), new FolderEntry("ensemble", false, false, false)); // Not used
+ }
+
+ addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", true, false, true));
+ addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", false, false, false));
+ addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", true, false, true));
+
+ addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", true, false, false)); // Not used?
+
+ addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", true, false, true));
+ addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", true, false, false));
+
+ addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", true, false, false));
+
+ addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", false, false, false));
+ addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", false, false, false));
+ addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", false, false, false));
+
+ addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", true, false, true));
+ addEntry(LLFolderType::FT_MATERIAL, new FolderEntry("material", true, false, true));
+
+ addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", false, false, false));
+};
+
+// static
+LLFolderType::EType LLFolderType::lookup(const std::string& name)
+{
+ return LLFolderDictionary::getInstance()->lookup(name);
+}
+
+// static
+const std::string &LLFolderType::lookup(LLFolderType::EType folder_type)
+{
+ const FolderEntry *entry = LLFolderDictionary::getInstance()->lookup(folder_type);
+ if (entry)
+ {
+ return entry->mName;
+ }
+ else
+ {
+ return badLookup();
+ }
+}
+
+// static
+// Only plain folders and a few other types aren't protected. "Protected" means
+// you can't move, deleted, or change certain properties such as their type.
+bool LLFolderType::lookupIsProtectedType(EType folder_type)
+{
+ const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
+ const FolderEntry *entry = dict->lookup(folder_type);
+ if (entry)
+ {
+ return entry->mIsProtected;
+ }
+ return true;
+}
+
+// static
+// Is this folder type automatically created outside the viewer?
+bool LLFolderType::lookupIsAutomaticType(EType folder_type)
+{
+ const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
+ const FolderEntry *entry = dict->lookup(folder_type);
+ if (entry)
+ {
+ return entry->mIsAutomatic;
+ }
+ return true;
+}
+
+// static
+// Should this folder always exist as a single copy under (or as) the root?
+bool LLFolderType::lookupIsSingletonType(EType folder_type)
+{
+ const LLFolderDictionary *dict = LLFolderDictionary::getInstance();
+ const FolderEntry *entry = dict->lookup(folder_type);
+ if (entry)
+ {
+ return entry->mIsSingleton;
+ }
+ return true;
+}
+
+// static
+bool LLFolderType::lookupIsEnsembleType(EType folder_type)
+{
+ return (folder_type >= FT_ENSEMBLE_START &&
+ folder_type <= FT_ENSEMBLE_END);
+}
+
+// static
+LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type)
+{
+ if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP)
+ {
+ LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL;
+ }
+ return (LLAssetType::EType)folder_type;
+}
+
+// static
+LLFolderType::EType LLFolderType::assetTypeToFolderType(LLAssetType::EType asset_type)
+{
+ if (LLFolderType::lookup(LLFolderType::EType(asset_type)) == LLFolderType::badLookup())
+ {
+ LL_WARNS() << "Converting to unknown folder type " << asset_type << LL_ENDL;
+ }
+ return (LLFolderType::EType)asset_type;
+}
+
+// static
+const std::string &LLFolderType::badLookup()
+{
+ static const std::string sBadLookup = "llfoldertype_bad_lookup";
+ return sBadLookup;
+}
diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h index 19f4d61b5b..46a1b92a96 100644 --- a/indra/llinventory/llfoldertype.h +++ b/indra/llinventory/llfoldertype.h @@ -1,25 +1,25 @@ -/** +/** * @file llfoldertype.h * @brief Declaration of LLFolderType. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,89 +35,89 @@ class LL_COMMON_API LLFolderType { public: - // ! BACKWARDS COMPATIBILITY ! Folder type enums must match asset type enums. - enum EType - { - FT_TEXTURE = 0, + // ! BACKWARDS COMPATIBILITY ! Folder type enums must match asset type enums. + enum EType + { + FT_TEXTURE = 0, + + FT_SOUND = 1, - FT_SOUND = 1, + FT_CALLINGCARD = 2, - FT_CALLINGCARD = 2, + FT_LANDMARK = 3, - FT_LANDMARK = 3, + FT_CLOTHING = 5, - FT_CLOTHING = 5, + FT_OBJECT = 6, - FT_OBJECT = 6, + FT_NOTECARD = 7, - FT_NOTECARD = 7, + FT_ROOT_INVENTORY = 8, + // We'd really like to change this to 9 since AT_CATEGORY is 8, + // but "My Inventory" has been type 8 for a long time. - FT_ROOT_INVENTORY = 8, - // We'd really like to change this to 9 since AT_CATEGORY is 8, - // but "My Inventory" has been type 8 for a long time. + FT_LSL_TEXT = 10, - FT_LSL_TEXT = 10, + FT_BODYPART = 13, - FT_BODYPART = 13, + FT_TRASH = 14, - FT_TRASH = 14, + FT_SNAPSHOT_CATEGORY = 15, - FT_SNAPSHOT_CATEGORY = 15, + FT_LOST_AND_FOUND = 16, - FT_LOST_AND_FOUND = 16, + FT_ANIMATION = 20, - FT_ANIMATION = 20, + FT_GESTURE = 21, - FT_GESTURE = 21, + FT_FAVORITE = 23, - FT_FAVORITE = 23, + FT_ENSEMBLE_START = 26, + FT_ENSEMBLE_END = 45, + // This range is reserved for special clothing folder types. - FT_ENSEMBLE_START = 26, - FT_ENSEMBLE_END = 45, - // This range is reserved for special clothing folder types. + FT_CURRENT_OUTFIT = 46, + FT_OUTFIT = 47, + FT_MY_OUTFITS = 48, - FT_CURRENT_OUTFIT = 46, - FT_OUTFIT = 47, - FT_MY_OUTFITS = 48, - - FT_MESH = 49, + FT_MESH = 49, - FT_INBOX = 50, - FT_OUTBOX = 51, + FT_INBOX = 50, + FT_OUTBOX = 51, - FT_BASIC_ROOT = 52, + FT_BASIC_ROOT = 52, - FT_MARKETPLACE_LISTINGS = 53, - FT_MARKETPLACE_STOCK = 54, - FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only. + FT_MARKETPLACE_LISTINGS = 53, + FT_MARKETPLACE_STOCK = 54, + FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only. FT_SETTINGS = 56, FT_MATERIAL = 57, - FT_COUNT, + FT_COUNT, - FT_NONE = -1 + FT_NONE = -1 // When adding, see note at bottom of LLAssetType::Etype - }; + }; - static EType lookup(const std::string& type_name); - static const std::string& lookup(EType folder_type); + static EType lookup(const std::string& type_name); + static const std::string& lookup(EType folder_type); - static bool lookupIsProtectedType(EType folder_type); - static bool lookupIsAutomaticType(EType folder_type); - static bool lookupIsSingletonType(EType folder_type); - static bool lookupIsEnsembleType(EType folder_type); + static bool lookupIsProtectedType(EType folder_type); + static bool lookupIsAutomaticType(EType folder_type); + static bool lookupIsSingletonType(EType folder_type); + static bool lookupIsEnsembleType(EType folder_type); - static LLAssetType::EType folderTypeToAssetType(LLFolderType::EType folder_type); - static LLFolderType::EType assetTypeToFolderType(LLAssetType::EType asset_type); + static LLAssetType::EType folderTypeToAssetType(LLFolderType::EType folder_type); + static LLFolderType::EType assetTypeToFolderType(LLAssetType::EType asset_type); - static const std::string& badLookup(); // error string when a lookup fails + static const std::string& badLookup(); // error string when a lookup fails protected: - LLFolderType() {} - ~LLFolderType() {} + LLFolderType() {} + ~LLFolderType() {} }; #endif // LL_LLFOLDERTYPE_H diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index d220731f6a..55e8294619 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -1,1517 +1,1517 @@ -/** - * @file llinventory.cpp - * @brief Implementation of the inventory system. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llinventory.h" - -#include "lldbstrings.h" -#include "llfasttimer.h" -#include "llinventorydefines.h" -#include "llxorcipher.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "message.h" -#include <boost/tokenizer.hpp> - -#include "llsdutil.h" - -///---------------------------------------------------------------------------- -/// Exported functions -///---------------------------------------------------------------------------- -// FIXME D567 - what's the point of these, especially if we don't even use them consistently? -static const std::string INV_ITEM_ID_LABEL("item_id"); -static const std::string INV_FOLDER_ID_LABEL("cat_id"); -static const std::string INV_PARENT_ID_LABEL("parent_id"); -static const std::string INV_THUMBNAIL_LABEL("thumbnail"); -static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id"); -static const std::string INV_ASSET_TYPE_LABEL("type"); -static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type"); -static const std::string INV_INVENTORY_TYPE_LABEL("inv_type"); -static const std::string INV_NAME_LABEL("name"); -static const std::string INV_DESC_LABEL("desc"); -static const std::string INV_PERMISSIONS_LABEL("permissions"); -static const std::string INV_SHADOW_ID_LABEL("shadow_id"); -static const std::string INV_ASSET_ID_LABEL("asset_id"); -static const std::string INV_LINKED_ID_LABEL("linked_id"); -static const std::string INV_SALE_INFO_LABEL("sale_info"); -static const std::string INV_FLAGS_LABEL("flags"); -static const std::string INV_CREATION_DATE_LABEL("created_at"); - -// key used by agent-inventory-service -static const std::string INV_ASSET_TYPE_LABEL_WS("type_default"); -static const std::string INV_FOLDER_ID_LABEL_WS("category_id"); - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730"); - -///---------------------------------------------------------------------------- -/// Class LLInventoryObject -///---------------------------------------------------------------------------- - -LLInventoryObject::LLInventoryObject(const LLUUID& uuid, - const LLUUID& parent_uuid, - LLAssetType::EType type, - const std::string& name) -: mUUID(uuid), - mParentUUID(parent_uuid), - mType(type), - mName(name), - mCreationDate(0) -{ - correctInventoryName(mName); -} - -LLInventoryObject::LLInventoryObject() -: mType(LLAssetType::AT_NONE), - mCreationDate(0) -{ -} - -LLInventoryObject::~LLInventoryObject() -{ -} - -void LLInventoryObject::copyObject(const LLInventoryObject* other) -{ - mUUID = other->mUUID; - mParentUUID = other->mParentUUID; - mType = other->mType; - mName = other->mName; - mThumbnailUUID = other->mThumbnailUUID; -} - -const LLUUID& LLInventoryObject::getUUID() const -{ - return mUUID; -} - -const LLUUID& LLInventoryObject::getParentUUID() const -{ - return mParentUUID; -} - -const LLUUID& LLInventoryObject::getThumbnailUUID() const -{ - return mThumbnailUUID; -} - -const std::string& LLInventoryObject::getName() const -{ - return mName; -} - -// To bypass linked items, since llviewerinventory's getType -// will return the linked-to item's type instead of this object's type. -LLAssetType::EType LLInventoryObject::getActualType() const -{ - return mType; -} - -bool LLInventoryObject::getIsLinkType() const -{ - return LLAssetType::lookupIsLinkType(mType); -} - -// See LLInventoryItem override. -// virtual -const LLUUID& LLInventoryObject::getLinkedUUID() const -{ - return mUUID; -} - -LLAssetType::EType LLInventoryObject::getType() const -{ - return mType; -} - -void LLInventoryObject::setUUID(const LLUUID& new_uuid) -{ - mUUID = new_uuid; -} - -void LLInventoryObject::rename(const std::string& n) -{ - std::string new_name(n); - correctInventoryName(new_name); - if( !new_name.empty() && new_name != mName ) - { - mName = new_name; - } -} - -void LLInventoryObject::setParent(const LLUUID& new_parent) -{ - mParentUUID = new_parent; -} - -void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid) -{ - mThumbnailUUID = thumbnail_uuid; -} - -void LLInventoryObject::setType(LLAssetType::EType type) -{ - mType = type; -} - - -// virtual -bool LLInventoryObject::importLegacyStream(std::istream& input_stream) -{ - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - - keyword[0] = '\0'; - valuestr[0] = '\0'; - while(input_stream.good()) - { - input_stream.getline(buffer, MAX_STRING); - sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */ - if(0 == strcmp("{",keyword)) - { - continue; - } - if(0 == strcmp("}", keyword)) - { - break; - } - else if(0 == strcmp("obj_id", keyword)) - { - mUUID.set(valuestr); - } - else if(0 == strcmp("parent_id", keyword)) - { - mParentUUID.set(valuestr); - } - else if(0 == strcmp("type", keyword)) - { - mType = LLAssetType::lookup(valuestr); - } - else if (0 == strcmp("metadata", keyword)) - { - LLSD metadata; - if (strncmp("<llsd>", valuestr, 6) == 0) - { - std::istringstream stream(valuestr); - LLSDSerialize::fromXML(metadata, stream); - } - else - { - // next line likely contains metadata, but at the moment is not supported - // can do something like: - // LLSDSerialize::fromNotation(metadata, input_stream, -1); - } - - if (metadata.has("thumbnail")) - { - const LLSD& thumbnail = metadata["thumbnail"]; - if (thumbnail.has("asset_id")) - { - setThumbnailUUID(thumbnail["asset_id"].asUUID()); - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else if(0 == strcmp("name", keyword)) - { - //strcpy(valuestr, buffer + strlen(keyword) + 3); - // *NOTE: Not ANSI C, but widely supported. - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254[^|]", - keyword, valuestr); - mName.assign(valuestr); - correctInventoryName(mName); - } - else - { - LL_WARNS() << "unknown keyword '" << keyword - << "' in LLInventoryObject::importLegacyStream() for object " << mUUID << LL_ENDL; - } - } - return true; -} - -bool LLInventoryObject::exportLegacyStream(std::ostream& output_stream, bool) const -{ - std::string uuid_str; - output_stream << "\tinv_object\t0\n\t{\n"; - mUUID.toString(uuid_str); - output_stream << "\t\tobj_id\t" << uuid_str << "\n"; - mParentUUID.toString(uuid_str); - output_stream << "\t\tparent_id\t" << uuid_str << "\n"; - output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n"; - output_stream << "\t\tname\t" << mName.c_str() << "|\n"; - output_stream << "\t}\n"; - return true; -} - -void LLInventoryObject::updateParentOnServer(bool) const -{ - // don't do nothin' - LL_WARNS() << "LLInventoryObject::updateParentOnServer() called. Doesn't do anything." << LL_ENDL; -} - -void LLInventoryObject::updateServer(bool) const -{ - // don't do nothin' - LL_WARNS() << "LLInventoryObject::updateServer() called. Doesn't do anything." << LL_ENDL; -} - -// static -void LLInventoryObject::correctInventoryName(std::string& name) -{ - LLStringUtil::replaceNonstandardASCII(name, ' '); - LLStringUtil::replaceChar(name, '|', ' '); - LLStringUtil::trim(name); - LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN); -} - -time_t LLInventoryObject::getCreationDate() const -{ - return mCreationDate; -} - -void LLInventoryObject::setCreationDate(time_t creation_date_utc) -{ - mCreationDate = creation_date_utc; -} - - -const std::string& LLInventoryItem::getDescription() const -{ - return mDescription; -} - -const std::string& LLInventoryItem::getActualDescription() const -{ - return mDescription; -} - -///---------------------------------------------------------------------------- -/// Class LLInventoryItem -///---------------------------------------------------------------------------- - -LLInventoryItem::LLInventoryItem(const LLUUID& uuid, - const LLUUID& parent_uuid, - const LLPermissions& permissions, - const LLUUID& asset_uuid, - LLAssetType::EType type, - LLInventoryType::EType inv_type, - const std::string& name, - const std::string& desc, - const LLSaleInfo& sale_info, - U32 flags, - S32 creation_date_utc) : - LLInventoryObject(uuid, parent_uuid, type, name), - mPermissions(permissions), - mAssetUUID(asset_uuid), - mDescription(desc), - mSaleInfo(sale_info), - mInventoryType(inv_type), - mFlags(flags) -{ - mCreationDate = creation_date_utc; - - LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - LLStringUtil::replaceChar(mDescription, '|', ' '); - - mPermissions.initMasks(inv_type); -} - -LLInventoryItem::LLInventoryItem() : - LLInventoryObject(), - mPermissions(), - mAssetUUID(), - mDescription(), - mSaleInfo(), - mInventoryType(LLInventoryType::IT_NONE), - mFlags(0) -{ - mCreationDate = 0; -} - -LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) : - LLInventoryObject() -{ - copyItem(other); -} - -LLInventoryItem::~LLInventoryItem() -{ -} - -// virtual -void LLInventoryItem::copyItem(const LLInventoryItem* other) -{ - copyObject(other); - mPermissions = other->mPermissions; - mAssetUUID = other->mAssetUUID; - mThumbnailUUID = other->mThumbnailUUID; - mDescription = other->mDescription; - mSaleInfo = other->mSaleInfo; - mInventoryType = other->mInventoryType; - mFlags = other->mFlags; - mCreationDate = other->mCreationDate; -} - -// If this is a linked item, then the UUID of the base object is -// this item's assetID. -// virtual -const LLUUID& LLInventoryItem::getLinkedUUID() const -{ - if (LLAssetType::lookupIsLinkType(getActualType())) - { - return mAssetUUID; - } - - return LLInventoryObject::getLinkedUUID(); -} - -const LLPermissions& LLInventoryItem::getPermissions() const -{ - return mPermissions; -} - -const LLUUID& LLInventoryItem::getCreatorUUID() const -{ - return mPermissions.getCreator(); -} - -const LLUUID& LLInventoryItem::getAssetUUID() const -{ - return mAssetUUID; -} - -void LLInventoryItem::setAssetUUID(const LLUUID& asset_id) -{ - mAssetUUID = asset_id; -} - - -U32 LLInventoryItem::getCRC32() const -{ - // *FIX: Not a real crc - more of a checksum. - // *NOTE: We currently do not validate the name or description, - // but if they change in transit, it's no big deal. - U32 crc = mUUID.getCRC32(); - //LL_DEBUGS() << "1 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mParentUUID.getCRC32(); - //LL_DEBUGS() << "2 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mPermissions.getCRC32(); - //LL_DEBUGS() << "3 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mAssetUUID.getCRC32(); - //LL_DEBUGS() << "4 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mType; - //LL_DEBUGS() << "5 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mInventoryType; - //LL_DEBUGS() << "6 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mFlags; - //LL_DEBUGS() << "7 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mSaleInfo.getCRC32(); - //LL_DEBUGS() << "8 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += (U32)mCreationDate; - //LL_DEBUGS() << "9 crc: " << std::hex << crc << std::dec << LL_ENDL; - crc += mThumbnailUUID.getCRC32(); - return crc; -} - -// static -void LLInventoryItem::correctInventoryDescription(std::string& desc) -{ - LLStringUtil::replaceNonstandardASCII(desc, ' '); - LLStringUtil::replaceChar(desc, '|', ' '); -} - -void LLInventoryItem::setDescription(const std::string& d) -{ - std::string new_desc(d); - LLInventoryItem::correctInventoryDescription(new_desc); - if( new_desc != mDescription ) - { - mDescription = new_desc; - } -} - -void LLInventoryItem::setPermissions(const LLPermissions& perm) -{ - mPermissions = perm; - - // Override permissions to unrestricted if this is a landmark - mPermissions.initMasks(mInventoryType); -} - -void LLInventoryItem::setInventoryType(LLInventoryType::EType inv_type) -{ - mInventoryType = inv_type; -} - -void LLInventoryItem::setFlags(U32 flags) -{ - mFlags = flags; -} - -// Currently only used in the Viewer to handle calling cards -// where the creator is actually used to store the target. -void LLInventoryItem::setCreator(const LLUUID& creator) -{ - mPermissions.setCreator(creator); -} - -void LLInventoryItem::accumulatePermissionSlamBits(const LLInventoryItem& old_item) -{ - // Remove any pre-existing II_FLAGS_PERM_OVERWRITE_MASK flags - // because we now detect when they should be set. - setFlags( old_item.getFlags() | (getFlags() & ~(LLInventoryItemFlags::II_FLAGS_PERM_OVERWRITE_MASK)) ); - - // Enforce the PERM_OVERWRITE flags for any masks that are different - // but only for AT_OBJECT's since that is the only asset type that can - // exist in-world (instead of only in-inventory or in-object-contents). - if (LLAssetType::AT_OBJECT == getType()) - { - LLPermissions old_permissions = old_item.getPermissions(); - U32 flags_to_be_set = 0; - if(old_permissions.getMaskNextOwner() != getPermissions().getMaskNextOwner()) - { - flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM; - } - if(old_permissions.getMaskEveryone() != getPermissions().getMaskEveryone()) - { - flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; - } - if(old_permissions.getMaskGroup() != getPermissions().getMaskGroup()) - { - flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; - } - LLSaleInfo old_sale_info = old_item.getSaleInfo(); - if(old_sale_info != getSaleInfo()) - { - flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE; - } - setFlags(getFlags() | flags_to_be_set); - } -} - -const LLSaleInfo& LLInventoryItem::getSaleInfo() const -{ - return mSaleInfo; -} - -void LLInventoryItem::setSaleInfo(const LLSaleInfo& sale_info) -{ - mSaleInfo = sale_info; -} - -LLInventoryType::EType LLInventoryItem::getInventoryType() const -{ - return mInventoryType; -} - -U32 LLInventoryItem::getFlags() const -{ - return mFlags; -} - -time_t LLInventoryItem::getCreationDate() const -{ - return mCreationDate; -} - - -// virtual -void LLInventoryItem::packMessage(LLMessageSystem* msg) const -{ - msg->addUUIDFast(_PREHASH_ItemID, mUUID); - msg->addUUIDFast(_PREHASH_FolderID, mParentUUID); - mPermissions.packMessage(msg); - msg->addUUIDFast(_PREHASH_AssetID, mAssetUUID); - S8 type = static_cast<S8>(mType); - msg->addS8Fast(_PREHASH_Type, type); - type = static_cast<S8>(mInventoryType); - msg->addS8Fast(_PREHASH_InvType, type); - msg->addU32Fast(_PREHASH_Flags, mFlags); - mSaleInfo.packMessage(msg); - msg->addStringFast(_PREHASH_Name, mName); - msg->addStringFast(_PREHASH_Description, mDescription); - msg->addS32Fast(_PREHASH_CreationDate, (S32)mCreationDate); - U32 crc = getCRC32(); - msg->addU32Fast(_PREHASH_CRC, crc); -} - -// virtual -bool LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num) -{ - msg->getUUIDFast(block, _PREHASH_ItemID, mUUID, block_num); - msg->getUUIDFast(block, _PREHASH_FolderID, mParentUUID, block_num); - mPermissions.unpackMessage(msg, block, block_num); - msg->getUUIDFast(block, _PREHASH_AssetID, mAssetUUID, block_num); - - S8 type; - msg->getS8Fast(block, _PREHASH_Type, type, block_num); - mType = static_cast<LLAssetType::EType>(type); - msg->getS8(block, "InvType", type, block_num); - mInventoryType = static_cast<LLInventoryType::EType>(type); - mPermissions.initMasks(mInventoryType); - - msg->getU32Fast(block, _PREHASH_Flags, mFlags, block_num); - - mSaleInfo.unpackMultiMessage(msg, block, block_num); - - msg->getStringFast(block, _PREHASH_Name, mName, block_num); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - - msg->getStringFast(block, _PREHASH_Description, mDescription, block_num); - LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - - S32 date; - msg->getS32(block, "CreationDate", date, block_num); - mCreationDate = date; - - U32 local_crc = getCRC32(); - U32 remote_crc = 0; - msg->getU32(block, "CRC", remote_crc, block_num); -//#define CRC_CHECK -#ifdef CRC_CHECK - if(local_crc == remote_crc) - { - LL_DEBUGS() << "crc matches" << LL_ENDL; - return true; - } - else - { - LL_WARNS() << "inventory crc mismatch: local=" << std::hex << local_crc - << " remote=" << remote_crc << std::dec << LL_ENDL; - return false; - } -#else - return (local_crc == remote_crc); -#endif -} - -// virtual -bool LLInventoryItem::importLegacyStream(std::istream& input_stream) -{ - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - char junk[MAX_STRING]; /* Flawfinder: ignore */ - bool success = true; - - keyword[0] = '\0'; - valuestr[0] = '\0'; - - mInventoryType = LLInventoryType::IT_NONE; - mAssetUUID.setNull(); - while(success && input_stream.good()) - { - input_stream.getline(buffer, MAX_STRING); - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254s", - keyword, valuestr); - if(0 == strcmp("{",keyword)) - { - continue; - } - if(0 == strcmp("}", keyword)) - { - break; - } - else if(0 == strcmp("item_id", keyword)) - { - mUUID.set(valuestr); - } - else if(0 == strcmp("parent_id", keyword)) - { - mParentUUID.set(valuestr); - } - else if(0 == strcmp("permissions", keyword)) - { - success = mPermissions.importLegacyStream(input_stream); - } - else if(0 == strcmp("sale_info", keyword)) - { - // Sale info used to contain next owner perm. It is now in - // the permissions. Thus, we read that out, and fix legacy - // objects. It's possible this op would fail, but it - // should pick up the vast majority of the tasks. - bool has_perm_mask = false; - U32 perm_mask = 0; - success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask); - if(has_perm_mask) - { - if(perm_mask == PERM_NONE) - { - perm_mask = mPermissions.getMaskOwner(); - } - // fair use fix. - if(!(perm_mask & PERM_COPY)) - { - perm_mask |= PERM_TRANSFER; - } - mPermissions.setMaskNext(perm_mask); - } - } - else if(0 == strcmp("shadow_id", keyword)) - { - mAssetUUID.set(valuestr); - LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); - cipher.decrypt(mAssetUUID.mData, UUID_BYTES); - } - else if(0 == strcmp("asset_id", keyword)) - { - mAssetUUID.set(valuestr); - } - else if(0 == strcmp("type", keyword)) - { - mType = LLAssetType::lookup(valuestr); - } - else if (0 == strcmp("metadata", keyword)) - { - LLSD metadata; - if (strncmp("<llsd>", valuestr, 6) == 0) - { - std::istringstream stream(valuestr); - LLSDSerialize::fromXML(metadata, stream); - } - else - { - // next line likely contains metadata, but at the moment is not supported - // can do something like: - // LLSDSerialize::fromNotation(metadata, input_stream, -1); - } - - if (metadata.has("thumbnail")) - { - const LLSD& thumbnail = metadata["thumbnail"]; - if (thumbnail.has("asset_id")) - { - setThumbnailUUID(thumbnail["asset_id"].asUUID()); - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else if(0 == strcmp("inv_type", keyword)) - { - mInventoryType = LLInventoryType::lookup(std::string(valuestr)); - } - else if(0 == strcmp("flags", keyword)) - { - sscanf(valuestr, "%x", &mFlags); - } - else if(0 == strcmp("name", keyword)) - { - //strcpy(valuestr, buffer + strlen(keyword) + 3); - // *NOTE: Not ANSI C, but widely supported. - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s%254[\t]%254[^|]", - keyword, junk, valuestr); - - // IW: sscanf chokes and puts | in valuestr if there's no name - if (valuestr[0] == '|') - { - valuestr[0] = '\000'; - } - - mName.assign(valuestr); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - LLStringUtil::replaceChar(mName, '|', ' '); - } - else if(0 == strcmp("desc", keyword)) - { - //strcpy(valuestr, buffer + strlen(keyword) + 3); - // *NOTE: Not ANSI C, but widely supported. - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s%254[\t]%254[^|]", - keyword, junk, valuestr); - - if (valuestr[0] == '|') - { - valuestr[0] = '\000'; - } - - mDescription.assign(valuestr); - LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - /* TODO -- ask Ian about this code - const char *donkey = mDescription.c_str(); - if (donkey[0] == '|') - { - LL_ERRS() << "Donkey" << LL_ENDL; - } - */ - } - else if(0 == strcmp("creation_date", keyword)) - { - S32 date; - sscanf(valuestr, "%d", &date); - mCreationDate = date; - } - else - { - LL_WARNS() << "unknown keyword '" << keyword - << "' in inventory import of item " << mUUID << LL_ENDL; - } - } - - // Need to convert 1.0 simstate files to a useful inventory type - // and potentially deal with bad inventory tyes eg, a landmark - // marked as a texture. - if((LLInventoryType::IT_NONE == mInventoryType) - || !inventory_and_asset_types_match(mInventoryType, mType)) - { - LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL; - mInventoryType = LLInventoryType::defaultForAssetType(mType); - } - - mPermissions.initMasks(mInventoryType); - - return success; -} - -bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool include_asset_key) const -{ - std::string uuid_str; - output_stream << "\tinv_item\t0\n\t{\n"; - mUUID.toString(uuid_str); - output_stream << "\t\titem_id\t" << uuid_str << "\n"; - mParentUUID.toString(uuid_str); - output_stream << "\t\tparent_id\t" << uuid_str << "\n"; - mPermissions.exportLegacyStream(output_stream); - - if (mThumbnailUUID.notNull()) - { - // Max length is 255 chars, will have to export differently if it gets more data - // Ex: use newline and toNotation (uses {}) for unlimited size - LLSD metadata; - metadata["thumbnail"] = LLSD().with("asset_id", mThumbnailUUID); - - output_stream << "\t\tmetadata\t"; - LLSDSerialize::toXML(metadata, output_stream); - output_stream << "|\n"; - } - - // Check for permissions to see the asset id, and if so write it - // out as an asset id. Otherwise, apply our cheesy encryption. - if(include_asset_key) - { - U32 mask = mPermissions.getMaskBase(); - if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) - || (mAssetUUID.isNull())) - { - mAssetUUID.toString(uuid_str); - output_stream << "\t\tasset_id\t" << uuid_str << "\n"; - } - else - { - LLUUID shadow_id(mAssetUUID); - LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); - cipher.encrypt(shadow_id.mData, UUID_BYTES); - shadow_id.toString(uuid_str); - output_stream << "\t\tshadow_id\t" << uuid_str << "\n"; - } - } - else - { - LLUUID::null.toString(uuid_str); - output_stream << "\t\tasset_id\t" << uuid_str << "\n"; - } - output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n"; - const std::string inv_type_str = LLInventoryType::lookup(mInventoryType); - if(!inv_type_str.empty()) - output_stream << "\t\tinv_type\t" << inv_type_str << "\n"; - std::string buffer; - buffer = llformat( "\t\tflags\t%08x\n", mFlags); - output_stream << buffer; - mSaleInfo.exportLegacyStream(output_stream); - output_stream << "\t\tname\t" << mName.c_str() << "|\n"; - output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n"; - output_stream << "\t\tcreation_date\t" << mCreationDate << "\n"; - output_stream << "\t}\n"; - return true; -} - -LLSD LLInventoryItem::asLLSD() const -{ - LLSD sd = LLSD(); - asLLSD(sd); - return sd; -} - -void LLInventoryItem::asLLSD( LLSD& sd ) const -{ - sd[INV_ITEM_ID_LABEL] = mUUID; - sd[INV_PARENT_ID_LABEL] = mParentUUID; - sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions); - - if (mThumbnailUUID.notNull()) - { - sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); - } - - U32 mask = mPermissions.getMaskBase(); - if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) - || (mAssetUUID.isNull())) - { - sd[INV_ASSET_ID_LABEL] = mAssetUUID; - } - else - { - // *TODO: get rid of this. Phoenix 2008-01-30 - LLUUID shadow_id(mAssetUUID); - LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); - cipher.encrypt(shadow_id.mData, UUID_BYTES); - sd[INV_SHADOW_ID_LABEL] = shadow_id; - } - sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); - sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType; - const std::string inv_type_str = LLInventoryType::lookup(mInventoryType); - if(!inv_type_str.empty()) - { - sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str; - } - //sd[INV_FLAGS_LABEL] = (S32)mFlags; - sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); - sd[INV_SALE_INFO_LABEL] = mSaleInfo; - sd[INV_NAME_LABEL] = mName; - sd[INV_DESC_LABEL] = mDescription; - sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; -} - -bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) -{ - LL_PROFILE_ZONE_SCOPED; - if (is_new) - { - // If we're adding LLSD to an existing object, need avoid - // clobbering these fields. - mInventoryType = LLInventoryType::IT_NONE; - mAssetUUID.setNull(); - } - - // TODO - figure out if this should be moved into the noclobber fields above - mThumbnailUUID.setNull(); - - // iterate as map to avoid making unnecessary temp copies of everything - LLSD::map_const_iterator i, end; - end = sd.endMap(); - for (i = sd.beginMap(); i != end; ++i) - { - if (i->first == INV_ITEM_ID_LABEL) - { - mUUID = i->second; - continue; - } - - if (i->first == INV_PARENT_ID_LABEL) - { - mParentUUID = i->second; - continue; - } - - if (i->first == INV_THUMBNAIL_LABEL) - { - const LLSD &thumbnail_map = i->second; - const std::string w = INV_ASSET_ID_LABEL; - if (thumbnail_map.has(w)) - { - mThumbnailUUID = thumbnail_map[w]; - } - /* Example: - <key> asset_id </key> - <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid> - <key> perms </key> - <integer> 8 </integer> - <key>service</key> - <integer> 3 </integer> - <key>version</key> - <integer> 1 </key> - */ - continue; - } - - if (i->first == INV_THUMBNAIL_ID_LABEL) - { - mThumbnailUUID = i->second.asUUID(); - continue; - } - - if (i->first == INV_PERMISSIONS_LABEL) - { - mPermissions = ll_permissions_from_sd(i->second); - continue; - } - - if (i->first == INV_SALE_INFO_LABEL) - { - // Sale info used to contain next owner perm. It is now in - // the permissions. Thus, we read that out, and fix legacy - // objects. It's possible this op would fail, but it - // should pick up the vast majority of the tasks. - bool has_perm_mask = false; - U32 perm_mask = 0; - if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask)) - { - return false; - } - if (has_perm_mask) - { - if (perm_mask == PERM_NONE) - { - perm_mask = mPermissions.getMaskOwner(); - } - // fair use fix. - if (!(perm_mask & PERM_COPY)) - { - perm_mask |= PERM_TRANSFER; - } - mPermissions.setMaskNext(perm_mask); - } - continue; - } - - if (i->first == INV_SHADOW_ID_LABEL) - { - mAssetUUID = i->second; - LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); - cipher.decrypt(mAssetUUID.mData, UUID_BYTES); - continue; - } - - if (i->first == INV_ASSET_ID_LABEL) - { - mAssetUUID = i->second; - continue; - } - - if (i->first == INV_LINKED_ID_LABEL) - { - mAssetUUID = i->second; - continue; - } - - if (i->first == INV_ASSET_TYPE_LABEL) - { - LLSD const &label = i->second; - if (label.isString()) - { - mType = LLAssetType::lookup(label.asString().c_str()); - } - else if (label.isInteger()) - { - S8 type = (U8) label.asInteger(); - mType = static_cast<LLAssetType::EType>(type); - } - continue; - } - - if (i->first == INV_INVENTORY_TYPE_LABEL) - { - LLSD const &label = i->second; - if (label.isString()) - { - mInventoryType = LLInventoryType::lookup(label.asString().c_str()); - } - else if (label.isInteger()) - { - S8 type = (U8) label.asInteger(); - mInventoryType = static_cast<LLInventoryType::EType>(type); - } - continue; - } - - if (i->first == INV_FLAGS_LABEL) - { - LLSD const &label = i->second; - if (label.isBinary()) - { - mFlags = ll_U32_from_sd(label); - } - else if (label.isInteger()) - { - mFlags = label.asInteger(); - } - continue; - } - - if (i->first == INV_NAME_LABEL) - { - mName = i->second.asString(); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - LLStringUtil::replaceChar(mName, '|', ' '); - continue; - } - - if (i->first == INV_DESC_LABEL) - { - mDescription = i->second.asString(); - LLStringUtil::replaceNonstandardASCII(mDescription, ' '); - continue; - } - - if (i->first == INV_CREATION_DATE_LABEL) - { - mCreationDate = i->second.asInteger(); - continue; - } - } - - // Need to convert 1.0 simstate files to a useful inventory type - // and potentially deal with bad inventory tyes eg, a landmark - // marked as a texture. - if((LLInventoryType::IT_NONE == mInventoryType) - || !inventory_and_asset_types_match(mInventoryType, mType)) - { - LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL; - mInventoryType = LLInventoryType::defaultForAssetType(mType); - } - - mPermissions.initMasks(mInventoryType); - - return true; -} - -///---------------------------------------------------------------------------- -/// Class LLInventoryCategory -///---------------------------------------------------------------------------- - -LLInventoryCategory::LLInventoryCategory(const LLUUID& uuid, - const LLUUID& parent_uuid, - LLFolderType::EType preferred_type, - const std::string& name) : - LLInventoryObject(uuid, parent_uuid, LLAssetType::AT_CATEGORY, name), - mPreferredType(preferred_type) -{ -} - -LLInventoryCategory::LLInventoryCategory() : - mPreferredType(LLFolderType::FT_NONE) -{ - mType = LLAssetType::AT_CATEGORY; -} - -LLInventoryCategory::LLInventoryCategory(const LLInventoryCategory* other) : - LLInventoryObject() -{ - copyCategory(other); -} - -LLInventoryCategory::~LLInventoryCategory() -{ -} - -// virtual -void LLInventoryCategory::copyCategory(const LLInventoryCategory* other) -{ - copyObject(other); - mPreferredType = other->mPreferredType; -} - -LLFolderType::EType LLInventoryCategory::getPreferredType() const -{ - return mPreferredType; -} - -void LLInventoryCategory::setPreferredType(LLFolderType::EType type) -{ - mPreferredType = type; -} - -LLSD LLInventoryCategory::asLLSD() const -{ - LLSD sd = LLSD(); - sd[INV_ITEM_ID_LABEL] = mUUID; - sd[INV_PARENT_ID_LABEL] = mParentUUID; - S8 type = static_cast<S8>(mPreferredType); - sd[INV_ASSET_TYPE_LABEL] = type; - sd[INV_NAME_LABEL] = mName; - - if (mThumbnailUUID.notNull()) - { - sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); - } - - return sd; -} - -LLSD LLInventoryCategory::asAISCreateCatLLSD() const -{ - LLSD sd = LLSD(); - sd[INV_FOLDER_ID_LABEL_WS] = mUUID; - sd[INV_PARENT_ID_LABEL] = mParentUUID; - S8 type = static_cast<S8>(mPreferredType); - sd[INV_ASSET_TYPE_LABEL_WS] = type; - sd[INV_NAME_LABEL] = mName; - if (mThumbnailUUID.notNull()) - { - sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); - } - - return sd; -} - - -// virtual -void LLInventoryCategory::packMessage(LLMessageSystem* msg) const -{ - msg->addUUIDFast(_PREHASH_FolderID, mUUID); - msg->addUUIDFast(_PREHASH_ParentID, mParentUUID); - S8 type = static_cast<S8>(mPreferredType); - msg->addS8Fast(_PREHASH_Type, type); - msg->addStringFast(_PREHASH_Name, mName); -} - -bool LLInventoryCategory::fromLLSD(const LLSD& sd) -{ - std::string w; - - w = INV_FOLDER_ID_LABEL_WS; - if (sd.has(w)) - { - mUUID = sd[w]; - } - w = INV_PARENT_ID_LABEL; - if (sd.has(w)) - { - mParentUUID = sd[w]; - } - mThumbnailUUID.setNull(); - w = INV_THUMBNAIL_LABEL; - if (sd.has(w)) - { - const LLSD &thumbnail_map = sd[w]; - w = INV_ASSET_ID_LABEL; - if (thumbnail_map.has(w)) - { - mThumbnailUUID = thumbnail_map[w]; - } - } - else - { - w = INV_THUMBNAIL_ID_LABEL; - if (sd.has(w)) - { - mThumbnailUUID = sd[w]; - } - } - w = INV_ASSET_TYPE_LABEL; - if (sd.has(w)) - { - S8 type = (U8)sd[w].asInteger(); - mPreferredType = static_cast<LLFolderType::EType>(type); - } - w = INV_ASSET_TYPE_LABEL_WS; - if (sd.has(w)) - { - S8 type = (U8)sd[w].asInteger(); - mPreferredType = static_cast<LLFolderType::EType>(type); - } - - w = INV_NAME_LABEL; - if (sd.has(w)) - { - mName = sd[w].asString(); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - LLStringUtil::replaceChar(mName, '|', ' '); - } - return true; -} - -// virtual -void LLInventoryCategory::unpackMessage(LLMessageSystem* msg, - const char* block, - S32 block_num) -{ - msg->getUUIDFast(block, _PREHASH_FolderID, mUUID, block_num); - msg->getUUIDFast(block, _PREHASH_ParentID, mParentUUID, block_num); - S8 type; - msg->getS8Fast(block, _PREHASH_Type, type, block_num); - mPreferredType = static_cast<LLFolderType::EType>(type); - msg->getStringFast(block, _PREHASH_Name, mName, block_num); - LLStringUtil::replaceNonstandardASCII(mName, ' '); -} - -// virtual -bool LLInventoryCategory::importLegacyStream(std::istream& input_stream) -{ - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - - keyword[0] = '\0'; - valuestr[0] = '\0'; - while(input_stream.good()) - { - input_stream.getline(buffer, MAX_STRING); - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254s", - keyword, valuestr); - if(0 == strcmp("{",keyword)) - { - continue; - } - if(0 == strcmp("}", keyword)) - { - break; - } - else if(0 == strcmp("cat_id", keyword)) - { - mUUID.set(valuestr); - } - else if(0 == strcmp("parent_id", keyword)) - { - mParentUUID.set(valuestr); - } - else if(0 == strcmp("type", keyword)) - { - mType = LLAssetType::lookup(valuestr); - } - else if(0 == strcmp("pref_type", keyword)) - { - mPreferredType = LLFolderType::lookup(valuestr); - } - else if(0 == strcmp("name", keyword)) - { - //strcpy(valuestr, buffer + strlen(keyword) + 3); - // *NOTE: Not ANSI C, but widely supported. - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254[^|]", - keyword, valuestr); - mName.assign(valuestr); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - LLStringUtil::replaceChar(mName, '|', ' '); - } - else if (0 == strcmp("metadata", keyword)) - { - LLSD metadata; - if (strncmp("<llsd>", valuestr, 6) == 0) - { - std::istringstream stream(valuestr); - LLSDSerialize::fromXML(metadata, stream); - } - else - { - // next line likely contains metadata, but at the moment is not supported - // can do something like: - // LLSDSerialize::fromNotation(metadata, input_stream, -1); - } - - if (metadata.has("thumbnail")) - { - const LLSD& thumbnail = metadata["thumbnail"]; - if (thumbnail.has("asset_id")) - { - setThumbnailUUID(thumbnail["asset_id"].asUUID()); - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else - { - setThumbnailUUID(LLUUID::null); - } - } - else - { - LL_WARNS() << "unknown keyword '" << keyword - << "' in inventory import category " << mUUID << LL_ENDL; - } - } - return true; -} - -bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool) const -{ - std::string uuid_str; - output_stream << "\tinv_category\t0\n\t{\n"; - mUUID.toString(uuid_str); - output_stream << "\t\tcat_id\t" << uuid_str << "\n"; - mParentUUID.toString(uuid_str); - output_stream << "\t\tparent_id\t" << uuid_str << "\n"; - output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n"; - output_stream << "\t\tpref_type\t" << LLFolderType::lookup(mPreferredType) << "\n"; - output_stream << "\t\tname\t" << mName.c_str() << "|\n"; - if (mThumbnailUUID.notNull()) - { - // Only up to 255 chars - LLSD metadata; - metadata["thumbnail"] = LLSD().with("asset_id", mThumbnailUUID); - output_stream << "\t\tmetadata\t"; - LLSDSerialize::toXML(metadata, output_stream); - output_stream << "|\n"; - } - output_stream << "\t}\n"; - return true; -} - -LLSD LLInventoryCategory::exportLLSD() const -{ - LLSD cat_data; - cat_data[INV_FOLDER_ID_LABEL] = mUUID; - cat_data[INV_PARENT_ID_LABEL] = mParentUUID; - cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); - cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType); - cat_data[INV_NAME_LABEL] = mName; - - if (mThumbnailUUID.notNull()) - { - cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); - } - - return cat_data; -} - -bool LLInventoryCategory::importLLSD(const LLSD& cat_data) -{ - if (cat_data.has(INV_FOLDER_ID_LABEL)) - { - setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID()); - } - if (cat_data.has(INV_PARENT_ID_LABEL)) - { - setParent(cat_data[INV_PARENT_ID_LABEL].asUUID()); - } - if (cat_data.has(INV_ASSET_TYPE_LABEL)) - { - setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString())); - } - if (cat_data.has(INV_PREFERRED_TYPE_LABEL)) - { - setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString())); - } - if (cat_data.has(INV_THUMBNAIL_LABEL)) - { - LLUUID thumbnail_uuid; - const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL]; - if (thumbnail_data.has(INV_ASSET_ID_LABEL)) - { - thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID(); - } - setThumbnailUUID(thumbnail_uuid); - } - if (cat_data.has(INV_NAME_LABEL)) - { - mName = cat_data[INV_NAME_LABEL].asString(); - LLStringUtil::replaceNonstandardASCII(mName, ' '); - LLStringUtil::replaceChar(mName, '|', ' '); - } - - return true; -} -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- - -LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item) -{ - LLSD rv; - if(item.isNull()) return rv; - if (item->getType() == LLAssetType::AT_NONE) - { - LL_WARNS() << "ll_create_sd_from_inventory_item() for item with AT_NONE" - << LL_ENDL; - return rv; - } - rv[INV_ITEM_ID_LABEL] = item->getUUID(); - rv[INV_PARENT_ID_LABEL] = item->getParentUUID(); - rv[INV_NAME_LABEL] = item->getName(); - rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(item->getType()); - rv[INV_ASSET_ID_LABEL] = item->getAssetUUID(); - rv[INV_DESC_LABEL] = item->getDescription(); - rv[INV_SALE_INFO_LABEL] = ll_create_sd_from_sale_info(item->getSaleInfo()); - rv[INV_PERMISSIONS_LABEL] = - ll_create_sd_from_permissions(item->getPermissions()); - rv[INV_INVENTORY_TYPE_LABEL] = - LLInventoryType::lookup(item->getInventoryType()); - rv[INV_FLAGS_LABEL] = (S32)item->getFlags(); - rv[INV_CREATION_DATE_LABEL] = (S32)item->getCreationDate(); - return rv; -} - -LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat) -{ - LLSD rv; - if(cat.isNull()) return rv; - if (cat->getType() == LLAssetType::AT_NONE) - { - LL_WARNS() << "ll_create_sd_from_inventory_category() for cat with AT_NONE" - << LL_ENDL; - return rv; - } - rv[INV_FOLDER_ID_LABEL] = cat->getUUID(); - rv[INV_PARENT_ID_LABEL] = cat->getParentUUID(); - rv[INV_NAME_LABEL] = cat->getName(); - rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(cat->getType()); - if(LLFolderType::lookupIsProtectedType(cat->getPreferredType())) - { - rv[INV_PREFERRED_TYPE_LABEL] = - LLFolderType::lookup(cat->getPreferredType()).c_str(); - } - return rv; -} - -LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat) -{ - LLPointer<LLInventoryCategory> rv = new LLInventoryCategory; - rv->setUUID(sd_cat[INV_FOLDER_ID_LABEL].asUUID()); - rv->setParent(sd_cat[INV_PARENT_ID_LABEL].asUUID()); - rv->rename(sd_cat[INV_NAME_LABEL].asString()); - rv->setType( - LLAssetType::lookup(sd_cat[INV_ASSET_TYPE_LABEL].asString())); - rv->setPreferredType( - LLFolderType::lookup( - sd_cat[INV_PREFERRED_TYPE_LABEL].asString())); - return rv; -} +/**
+ * @file llinventory.cpp
+ * @brief Implementation of the inventory system.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llinventory.h"
+
+#include "lldbstrings.h"
+#include "llfasttimer.h"
+#include "llinventorydefines.h"
+#include "llxorcipher.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "message.h"
+#include <boost/tokenizer.hpp>
+
+#include "llsdutil.h"
+
+///----------------------------------------------------------------------------
+/// Exported functions
+///----------------------------------------------------------------------------
+// FIXME D567 - what's the point of these, especially if we don't even use them consistently?
+static const std::string INV_ITEM_ID_LABEL("item_id");
+static const std::string INV_FOLDER_ID_LABEL("cat_id");
+static const std::string INV_PARENT_ID_LABEL("parent_id");
+static const std::string INV_THUMBNAIL_LABEL("thumbnail");
+static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id");
+static const std::string INV_ASSET_TYPE_LABEL("type");
+static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
+static const std::string INV_INVENTORY_TYPE_LABEL("inv_type");
+static const std::string INV_NAME_LABEL("name");
+static const std::string INV_DESC_LABEL("desc");
+static const std::string INV_PERMISSIONS_LABEL("permissions");
+static const std::string INV_SHADOW_ID_LABEL("shadow_id");
+static const std::string INV_ASSET_ID_LABEL("asset_id");
+static const std::string INV_LINKED_ID_LABEL("linked_id");
+static const std::string INV_SALE_INFO_LABEL("sale_info");
+static const std::string INV_FLAGS_LABEL("flags");
+static const std::string INV_CREATION_DATE_LABEL("created_at");
+
+// key used by agent-inventory-service
+static const std::string INV_ASSET_TYPE_LABEL_WS("type_default");
+static const std::string INV_FOLDER_ID_LABEL_WS("category_id");
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730");
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryObject
+///----------------------------------------------------------------------------
+
+LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ LLAssetType::EType type,
+ const std::string& name)
+: mUUID(uuid),
+ mParentUUID(parent_uuid),
+ mType(type),
+ mName(name),
+ mCreationDate(0)
+{
+ correctInventoryName(mName);
+}
+
+LLInventoryObject::LLInventoryObject()
+: mType(LLAssetType::AT_NONE),
+ mCreationDate(0)
+{
+}
+
+LLInventoryObject::~LLInventoryObject()
+{
+}
+
+void LLInventoryObject::copyObject(const LLInventoryObject* other)
+{
+ mUUID = other->mUUID;
+ mParentUUID = other->mParentUUID;
+ mType = other->mType;
+ mName = other->mName;
+ mThumbnailUUID = other->mThumbnailUUID;
+}
+
+const LLUUID& LLInventoryObject::getUUID() const
+{
+ return mUUID;
+}
+
+const LLUUID& LLInventoryObject::getParentUUID() const
+{
+ return mParentUUID;
+}
+
+const LLUUID& LLInventoryObject::getThumbnailUUID() const
+{
+ return mThumbnailUUID;
+}
+
+const std::string& LLInventoryObject::getName() const
+{
+ return mName;
+}
+
+// To bypass linked items, since llviewerinventory's getType
+// will return the linked-to item's type instead of this object's type.
+LLAssetType::EType LLInventoryObject::getActualType() const
+{
+ return mType;
+}
+
+bool LLInventoryObject::getIsLinkType() const
+{
+ return LLAssetType::lookupIsLinkType(mType);
+}
+
+// See LLInventoryItem override.
+// virtual
+const LLUUID& LLInventoryObject::getLinkedUUID() const
+{
+ return mUUID;
+}
+
+LLAssetType::EType LLInventoryObject::getType() const
+{
+ return mType;
+}
+
+void LLInventoryObject::setUUID(const LLUUID& new_uuid)
+{
+ mUUID = new_uuid;
+}
+
+void LLInventoryObject::rename(const std::string& n)
+{
+ std::string new_name(n);
+ correctInventoryName(new_name);
+ if( !new_name.empty() && new_name != mName )
+ {
+ mName = new_name;
+ }
+}
+
+void LLInventoryObject::setParent(const LLUUID& new_parent)
+{
+ mParentUUID = new_parent;
+}
+
+void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid)
+{
+ mThumbnailUUID = thumbnail_uuid;
+}
+
+void LLInventoryObject::setType(LLAssetType::EType type)
+{
+ mType = type;
+}
+
+
+// virtual
+bool LLInventoryObject::importLegacyStream(std::istream& input_stream)
+{
+ // *NOTE: Changing the buffer size will require changing the scanf
+ // calls below.
+ char buffer[MAX_STRING]; /* Flawfinder: ignore */
+ char keyword[MAX_STRING]; /* Flawfinder: ignore */
+ char valuestr[MAX_STRING]; /* Flawfinder: ignore */
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+ while(input_stream.good())
+ {
+ input_stream.getline(buffer, MAX_STRING);
+ sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */
+ if(0 == strcmp("{",keyword))
+ {
+ continue;
+ }
+ if(0 == strcmp("}", keyword))
+ {
+ break;
+ }
+ else if(0 == strcmp("obj_id", keyword))
+ {
+ mUUID.set(valuestr);
+ }
+ else if(0 == strcmp("parent_id", keyword))
+ {
+ mParentUUID.set(valuestr);
+ }
+ else if(0 == strcmp("type", keyword))
+ {
+ mType = LLAssetType::lookup(valuestr);
+ }
+ else if (0 == strcmp("metadata", keyword))
+ {
+ LLSD metadata;
+ if (strncmp("<llsd>", valuestr, 6) == 0)
+ {
+ std::istringstream stream(valuestr);
+ LLSDSerialize::fromXML(metadata, stream);
+ }
+ else
+ {
+ // next line likely contains metadata, but at the moment is not supported
+ // can do something like:
+ // LLSDSerialize::fromNotation(metadata, input_stream, -1);
+ }
+
+ if (metadata.has("thumbnail"))
+ {
+ const LLSD& thumbnail = metadata["thumbnail"];
+ if (thumbnail.has("asset_id"))
+ {
+ setThumbnailUUID(thumbnail["asset_id"].asUUID());
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else if(0 == strcmp("name", keyword))
+ {
+ //strcpy(valuestr, buffer + strlen(keyword) + 3);
+ // *NOTE: Not ANSI C, but widely supported.
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s %254[^|]",
+ keyword, valuestr);
+ mName.assign(valuestr);
+ correctInventoryName(mName);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword '" << keyword
+ << "' in LLInventoryObject::importLegacyStream() for object " << mUUID << LL_ENDL;
+ }
+ }
+ return true;
+}
+
+bool LLInventoryObject::exportLegacyStream(std::ostream& output_stream, bool) const
+{
+ std::string uuid_str;
+ output_stream << "\tinv_object\t0\n\t{\n";
+ mUUID.toString(uuid_str);
+ output_stream << "\t\tobj_id\t" << uuid_str << "\n";
+ mParentUUID.toString(uuid_str);
+ output_stream << "\t\tparent_id\t" << uuid_str << "\n";
+ output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
+ output_stream << "\t\tname\t" << mName.c_str() << "|\n";
+ output_stream << "\t}\n";
+ return true;
+}
+
+void LLInventoryObject::updateParentOnServer(bool) const
+{
+ // don't do nothin'
+ LL_WARNS() << "LLInventoryObject::updateParentOnServer() called. Doesn't do anything." << LL_ENDL;
+}
+
+void LLInventoryObject::updateServer(bool) const
+{
+ // don't do nothin'
+ LL_WARNS() << "LLInventoryObject::updateServer() called. Doesn't do anything." << LL_ENDL;
+}
+
+// static
+void LLInventoryObject::correctInventoryName(std::string& name)
+{
+ LLStringUtil::replaceNonstandardASCII(name, ' ');
+ LLStringUtil::replaceChar(name, '|', ' ');
+ LLStringUtil::trim(name);
+ LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);
+}
+
+time_t LLInventoryObject::getCreationDate() const
+{
+ return mCreationDate;
+}
+
+void LLInventoryObject::setCreationDate(time_t creation_date_utc)
+{
+ mCreationDate = creation_date_utc;
+}
+
+
+const std::string& LLInventoryItem::getDescription() const
+{
+ return mDescription;
+}
+
+const std::string& LLInventoryItem::getActualDescription() const
+{
+ return mDescription;
+}
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryItem
+///----------------------------------------------------------------------------
+
+LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ const LLPermissions& permissions,
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ LLInventoryType::EType inv_type,
+ const std::string& name,
+ const std::string& desc,
+ const LLSaleInfo& sale_info,
+ U32 flags,
+ S32 creation_date_utc) :
+ LLInventoryObject(uuid, parent_uuid, type, name),
+ mPermissions(permissions),
+ mAssetUUID(asset_uuid),
+ mDescription(desc),
+ mSaleInfo(sale_info),
+ mInventoryType(inv_type),
+ mFlags(flags)
+{
+ mCreationDate = creation_date_utc;
+
+ LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+ LLStringUtil::replaceChar(mDescription, '|', ' ');
+
+ mPermissions.initMasks(inv_type);
+}
+
+LLInventoryItem::LLInventoryItem() :
+ LLInventoryObject(),
+ mPermissions(),
+ mAssetUUID(),
+ mDescription(),
+ mSaleInfo(),
+ mInventoryType(LLInventoryType::IT_NONE),
+ mFlags(0)
+{
+ mCreationDate = 0;
+}
+
+LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
+ LLInventoryObject()
+{
+ copyItem(other);
+}
+
+LLInventoryItem::~LLInventoryItem()
+{
+}
+
+// virtual
+void LLInventoryItem::copyItem(const LLInventoryItem* other)
+{
+ copyObject(other);
+ mPermissions = other->mPermissions;
+ mAssetUUID = other->mAssetUUID;
+ mThumbnailUUID = other->mThumbnailUUID;
+ mDescription = other->mDescription;
+ mSaleInfo = other->mSaleInfo;
+ mInventoryType = other->mInventoryType;
+ mFlags = other->mFlags;
+ mCreationDate = other->mCreationDate;
+}
+
+// If this is a linked item, then the UUID of the base object is
+// this item's assetID.
+// virtual
+const LLUUID& LLInventoryItem::getLinkedUUID() const
+{
+ if (LLAssetType::lookupIsLinkType(getActualType()))
+ {
+ return mAssetUUID;
+ }
+
+ return LLInventoryObject::getLinkedUUID();
+}
+
+const LLPermissions& LLInventoryItem::getPermissions() const
+{
+ return mPermissions;
+}
+
+const LLUUID& LLInventoryItem::getCreatorUUID() const
+{
+ return mPermissions.getCreator();
+}
+
+const LLUUID& LLInventoryItem::getAssetUUID() const
+{
+ return mAssetUUID;
+}
+
+void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)
+{
+ mAssetUUID = asset_id;
+}
+
+
+U32 LLInventoryItem::getCRC32() const
+{
+ // *FIX: Not a real crc - more of a checksum.
+ // *NOTE: We currently do not validate the name or description,
+ // but if they change in transit, it's no big deal.
+ U32 crc = mUUID.getCRC32();
+ //LL_DEBUGS() << "1 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mParentUUID.getCRC32();
+ //LL_DEBUGS() << "2 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mPermissions.getCRC32();
+ //LL_DEBUGS() << "3 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mAssetUUID.getCRC32();
+ //LL_DEBUGS() << "4 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mType;
+ //LL_DEBUGS() << "5 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mInventoryType;
+ //LL_DEBUGS() << "6 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mFlags;
+ //LL_DEBUGS() << "7 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mSaleInfo.getCRC32();
+ //LL_DEBUGS() << "8 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += (U32)mCreationDate;
+ //LL_DEBUGS() << "9 crc: " << std::hex << crc << std::dec << LL_ENDL;
+ crc += mThumbnailUUID.getCRC32();
+ return crc;
+}
+
+// static
+void LLInventoryItem::correctInventoryDescription(std::string& desc)
+{
+ LLStringUtil::replaceNonstandardASCII(desc, ' ');
+ LLStringUtil::replaceChar(desc, '|', ' ');
+}
+
+void LLInventoryItem::setDescription(const std::string& d)
+{
+ std::string new_desc(d);
+ LLInventoryItem::correctInventoryDescription(new_desc);
+ if( new_desc != mDescription )
+ {
+ mDescription = new_desc;
+ }
+}
+
+void LLInventoryItem::setPermissions(const LLPermissions& perm)
+{
+ mPermissions = perm;
+
+ // Override permissions to unrestricted if this is a landmark
+ mPermissions.initMasks(mInventoryType);
+}
+
+void LLInventoryItem::setInventoryType(LLInventoryType::EType inv_type)
+{
+ mInventoryType = inv_type;
+}
+
+void LLInventoryItem::setFlags(U32 flags)
+{
+ mFlags = flags;
+}
+
+// Currently only used in the Viewer to handle calling cards
+// where the creator is actually used to store the target.
+void LLInventoryItem::setCreator(const LLUUID& creator)
+{
+ mPermissions.setCreator(creator);
+}
+
+void LLInventoryItem::accumulatePermissionSlamBits(const LLInventoryItem& old_item)
+{
+ // Remove any pre-existing II_FLAGS_PERM_OVERWRITE_MASK flags
+ // because we now detect when they should be set.
+ setFlags( old_item.getFlags() | (getFlags() & ~(LLInventoryItemFlags::II_FLAGS_PERM_OVERWRITE_MASK)) );
+
+ // Enforce the PERM_OVERWRITE flags for any masks that are different
+ // but only for AT_OBJECT's since that is the only asset type that can
+ // exist in-world (instead of only in-inventory or in-object-contents).
+ if (LLAssetType::AT_OBJECT == getType())
+ {
+ LLPermissions old_permissions = old_item.getPermissions();
+ U32 flags_to_be_set = 0;
+ if(old_permissions.getMaskNextOwner() != getPermissions().getMaskNextOwner())
+ {
+ flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM;
+ }
+ if(old_permissions.getMaskEveryone() != getPermissions().getMaskEveryone())
+ {
+ flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
+ }
+ if(old_permissions.getMaskGroup() != getPermissions().getMaskGroup())
+ {
+ flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
+ }
+ LLSaleInfo old_sale_info = old_item.getSaleInfo();
+ if(old_sale_info != getSaleInfo())
+ {
+ flags_to_be_set |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE;
+ }
+ setFlags(getFlags() | flags_to_be_set);
+ }
+}
+
+const LLSaleInfo& LLInventoryItem::getSaleInfo() const
+{
+ return mSaleInfo;
+}
+
+void LLInventoryItem::setSaleInfo(const LLSaleInfo& sale_info)
+{
+ mSaleInfo = sale_info;
+}
+
+LLInventoryType::EType LLInventoryItem::getInventoryType() const
+{
+ return mInventoryType;
+}
+
+U32 LLInventoryItem::getFlags() const
+{
+ return mFlags;
+}
+
+time_t LLInventoryItem::getCreationDate() const
+{
+ return mCreationDate;
+}
+
+
+// virtual
+void LLInventoryItem::packMessage(LLMessageSystem* msg) const
+{
+ msg->addUUIDFast(_PREHASH_ItemID, mUUID);
+ msg->addUUIDFast(_PREHASH_FolderID, mParentUUID);
+ mPermissions.packMessage(msg);
+ msg->addUUIDFast(_PREHASH_AssetID, mAssetUUID);
+ S8 type = static_cast<S8>(mType);
+ msg->addS8Fast(_PREHASH_Type, type);
+ type = static_cast<S8>(mInventoryType);
+ msg->addS8Fast(_PREHASH_InvType, type);
+ msg->addU32Fast(_PREHASH_Flags, mFlags);
+ mSaleInfo.packMessage(msg);
+ msg->addStringFast(_PREHASH_Name, mName);
+ msg->addStringFast(_PREHASH_Description, mDescription);
+ msg->addS32Fast(_PREHASH_CreationDate, (S32)mCreationDate);
+ U32 crc = getCRC32();
+ msg->addU32Fast(_PREHASH_CRC, crc);
+}
+
+// virtual
+bool LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
+{
+ msg->getUUIDFast(block, _PREHASH_ItemID, mUUID, block_num);
+ msg->getUUIDFast(block, _PREHASH_FolderID, mParentUUID, block_num);
+ mPermissions.unpackMessage(msg, block, block_num);
+ msg->getUUIDFast(block, _PREHASH_AssetID, mAssetUUID, block_num);
+
+ S8 type;
+ msg->getS8Fast(block, _PREHASH_Type, type, block_num);
+ mType = static_cast<LLAssetType::EType>(type);
+ msg->getS8(block, "InvType", type, block_num);
+ mInventoryType = static_cast<LLInventoryType::EType>(type);
+ mPermissions.initMasks(mInventoryType);
+
+ msg->getU32Fast(block, _PREHASH_Flags, mFlags, block_num);
+
+ mSaleInfo.unpackMultiMessage(msg, block, block_num);
+
+ msg->getStringFast(block, _PREHASH_Name, mName, block_num);
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+
+ msg->getStringFast(block, _PREHASH_Description, mDescription, block_num);
+ LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+
+ S32 date;
+ msg->getS32(block, "CreationDate", date, block_num);
+ mCreationDate = date;
+
+ U32 local_crc = getCRC32();
+ U32 remote_crc = 0;
+ msg->getU32(block, "CRC", remote_crc, block_num);
+//#define CRC_CHECK
+#ifdef CRC_CHECK
+ if(local_crc == remote_crc)
+ {
+ LL_DEBUGS() << "crc matches" << LL_ENDL;
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "inventory crc mismatch: local=" << std::hex << local_crc
+ << " remote=" << remote_crc << std::dec << LL_ENDL;
+ return false;
+ }
+#else
+ return (local_crc == remote_crc);
+#endif
+}
+
+// virtual
+bool LLInventoryItem::importLegacyStream(std::istream& input_stream)
+{
+ // *NOTE: Changing the buffer size will require changing the scanf
+ // calls below.
+ char buffer[MAX_STRING]; /* Flawfinder: ignore */
+ char keyword[MAX_STRING]; /* Flawfinder: ignore */
+ char valuestr[MAX_STRING]; /* Flawfinder: ignore */
+ char junk[MAX_STRING]; /* Flawfinder: ignore */
+ bool success = true;
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+
+ mInventoryType = LLInventoryType::IT_NONE;
+ mAssetUUID.setNull();
+ while(success && input_stream.good())
+ {
+ input_stream.getline(buffer, MAX_STRING);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s %254s",
+ keyword, valuestr);
+ if(0 == strcmp("{",keyword))
+ {
+ continue;
+ }
+ if(0 == strcmp("}", keyword))
+ {
+ break;
+ }
+ else if(0 == strcmp("item_id", keyword))
+ {
+ mUUID.set(valuestr);
+ }
+ else if(0 == strcmp("parent_id", keyword))
+ {
+ mParentUUID.set(valuestr);
+ }
+ else if(0 == strcmp("permissions", keyword))
+ {
+ success = mPermissions.importLegacyStream(input_stream);
+ }
+ else if(0 == strcmp("sale_info", keyword))
+ {
+ // Sale info used to contain next owner perm. It is now in
+ // the permissions. Thus, we read that out, and fix legacy
+ // objects. It's possible this op would fail, but it
+ // should pick up the vast majority of the tasks.
+ bool has_perm_mask = false;
+ U32 perm_mask = 0;
+ success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask);
+ if(has_perm_mask)
+ {
+ if(perm_mask == PERM_NONE)
+ {
+ perm_mask = mPermissions.getMaskOwner();
+ }
+ // fair use fix.
+ if(!(perm_mask & PERM_COPY))
+ {
+ perm_mask |= PERM_TRANSFER;
+ }
+ mPermissions.setMaskNext(perm_mask);
+ }
+ }
+ else if(0 == strcmp("shadow_id", keyword))
+ {
+ mAssetUUID.set(valuestr);
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
+ }
+ else if(0 == strcmp("asset_id", keyword))
+ {
+ mAssetUUID.set(valuestr);
+ }
+ else if(0 == strcmp("type", keyword))
+ {
+ mType = LLAssetType::lookup(valuestr);
+ }
+ else if (0 == strcmp("metadata", keyword))
+ {
+ LLSD metadata;
+ if (strncmp("<llsd>", valuestr, 6) == 0)
+ {
+ std::istringstream stream(valuestr);
+ LLSDSerialize::fromXML(metadata, stream);
+ }
+ else
+ {
+ // next line likely contains metadata, but at the moment is not supported
+ // can do something like:
+ // LLSDSerialize::fromNotation(metadata, input_stream, -1);
+ }
+
+ if (metadata.has("thumbnail"))
+ {
+ const LLSD& thumbnail = metadata["thumbnail"];
+ if (thumbnail.has("asset_id"))
+ {
+ setThumbnailUUID(thumbnail["asset_id"].asUUID());
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else if(0 == strcmp("inv_type", keyword))
+ {
+ mInventoryType = LLInventoryType::lookup(std::string(valuestr));
+ }
+ else if(0 == strcmp("flags", keyword))
+ {
+ sscanf(valuestr, "%x", &mFlags);
+ }
+ else if(0 == strcmp("name", keyword))
+ {
+ //strcpy(valuestr, buffer + strlen(keyword) + 3);
+ // *NOTE: Not ANSI C, but widely supported.
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s%254[\t]%254[^|]",
+ keyword, junk, valuestr);
+
+ // IW: sscanf chokes and puts | in valuestr if there's no name
+ if (valuestr[0] == '|')
+ {
+ valuestr[0] = '\000';
+ }
+
+ mName.assign(valuestr);
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ }
+ else if(0 == strcmp("desc", keyword))
+ {
+ //strcpy(valuestr, buffer + strlen(keyword) + 3);
+ // *NOTE: Not ANSI C, but widely supported.
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s%254[\t]%254[^|]",
+ keyword, junk, valuestr);
+
+ if (valuestr[0] == '|')
+ {
+ valuestr[0] = '\000';
+ }
+
+ mDescription.assign(valuestr);
+ LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+ /* TODO -- ask Ian about this code
+ const char *donkey = mDescription.c_str();
+ if (donkey[0] == '|')
+ {
+ LL_ERRS() << "Donkey" << LL_ENDL;
+ }
+ */
+ }
+ else if(0 == strcmp("creation_date", keyword))
+ {
+ S32 date;
+ sscanf(valuestr, "%d", &date);
+ mCreationDate = date;
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword '" << keyword
+ << "' in inventory import of item " << mUUID << LL_ENDL;
+ }
+ }
+
+ // Need to convert 1.0 simstate files to a useful inventory type
+ // and potentially deal with bad inventory tyes eg, a landmark
+ // marked as a texture.
+ if((LLInventoryType::IT_NONE == mInventoryType)
+ || !inventory_and_asset_types_match(mInventoryType, mType))
+ {
+ LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL;
+ mInventoryType = LLInventoryType::defaultForAssetType(mType);
+ }
+
+ mPermissions.initMasks(mInventoryType);
+
+ return success;
+}
+
+bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool include_asset_key) const
+{
+ std::string uuid_str;
+ output_stream << "\tinv_item\t0\n\t{\n";
+ mUUID.toString(uuid_str);
+ output_stream << "\t\titem_id\t" << uuid_str << "\n";
+ mParentUUID.toString(uuid_str);
+ output_stream << "\t\tparent_id\t" << uuid_str << "\n";
+ mPermissions.exportLegacyStream(output_stream);
+
+ if (mThumbnailUUID.notNull())
+ {
+ // Max length is 255 chars, will have to export differently if it gets more data
+ // Ex: use newline and toNotation (uses {}) for unlimited size
+ LLSD metadata;
+ metadata["thumbnail"] = LLSD().with("asset_id", mThumbnailUUID);
+
+ output_stream << "\t\tmetadata\t";
+ LLSDSerialize::toXML(metadata, output_stream);
+ output_stream << "|\n";
+ }
+
+ // Check for permissions to see the asset id, and if so write it
+ // out as an asset id. Otherwise, apply our cheesy encryption.
+ if(include_asset_key)
+ {
+ U32 mask = mPermissions.getMaskBase();
+ if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
+ || (mAssetUUID.isNull()))
+ {
+ mAssetUUID.toString(uuid_str);
+ output_stream << "\t\tasset_id\t" << uuid_str << "\n";
+ }
+ else
+ {
+ LLUUID shadow_id(mAssetUUID);
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.encrypt(shadow_id.mData, UUID_BYTES);
+ shadow_id.toString(uuid_str);
+ output_stream << "\t\tshadow_id\t" << uuid_str << "\n";
+ }
+ }
+ else
+ {
+ LLUUID::null.toString(uuid_str);
+ output_stream << "\t\tasset_id\t" << uuid_str << "\n";
+ }
+ output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
+ const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
+ if(!inv_type_str.empty())
+ output_stream << "\t\tinv_type\t" << inv_type_str << "\n";
+ std::string buffer;
+ buffer = llformat( "\t\tflags\t%08x\n", mFlags);
+ output_stream << buffer;
+ mSaleInfo.exportLegacyStream(output_stream);
+ output_stream << "\t\tname\t" << mName.c_str() << "|\n";
+ output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n";
+ output_stream << "\t\tcreation_date\t" << mCreationDate << "\n";
+ output_stream << "\t}\n";
+ return true;
+}
+
+LLSD LLInventoryItem::asLLSD() const
+{
+ LLSD sd = LLSD();
+ asLLSD(sd);
+ return sd;
+}
+
+void LLInventoryItem::asLLSD( LLSD& sd ) const
+{
+ sd[INV_ITEM_ID_LABEL] = mUUID;
+ sd[INV_PARENT_ID_LABEL] = mParentUUID;
+ sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions);
+
+ if (mThumbnailUUID.notNull())
+ {
+ sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
+ }
+
+ U32 mask = mPermissions.getMaskBase();
+ if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
+ || (mAssetUUID.isNull()))
+ {
+ sd[INV_ASSET_ID_LABEL] = mAssetUUID;
+ }
+ else
+ {
+ // *TODO: get rid of this. Phoenix 2008-01-30
+ LLUUID shadow_id(mAssetUUID);
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.encrypt(shadow_id.mData, UUID_BYTES);
+ sd[INV_SHADOW_ID_LABEL] = shadow_id;
+ }
+ sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
+ sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
+ const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
+ if(!inv_type_str.empty())
+ {
+ sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
+ }
+ //sd[INV_FLAGS_LABEL] = (S32)mFlags;
+ sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
+ sd[INV_SALE_INFO_LABEL] = mSaleInfo;
+ sd[INV_NAME_LABEL] = mName;
+ sd[INV_DESC_LABEL] = mDescription;
+ sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
+}
+
+bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ if (is_new)
+ {
+ // If we're adding LLSD to an existing object, need avoid
+ // clobbering these fields.
+ mInventoryType = LLInventoryType::IT_NONE;
+ mAssetUUID.setNull();
+ }
+
+ // TODO - figure out if this should be moved into the noclobber fields above
+ mThumbnailUUID.setNull();
+
+ // iterate as map to avoid making unnecessary temp copies of everything
+ LLSD::map_const_iterator i, end;
+ end = sd.endMap();
+ for (i = sd.beginMap(); i != end; ++i)
+ {
+ if (i->first == INV_ITEM_ID_LABEL)
+ {
+ mUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_PARENT_ID_LABEL)
+ {
+ mParentUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_THUMBNAIL_LABEL)
+ {
+ const LLSD &thumbnail_map = i->second;
+ const std::string w = INV_ASSET_ID_LABEL;
+ if (thumbnail_map.has(w))
+ {
+ mThumbnailUUID = thumbnail_map[w];
+ }
+ /* Example:
+ <key> asset_id </key>
+ <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
+ <key> perms </key>
+ <integer> 8 </integer>
+ <key>service</key>
+ <integer> 3 </integer>
+ <key>version</key>
+ <integer> 1 </key>
+ */
+ continue;
+ }
+
+ if (i->first == INV_THUMBNAIL_ID_LABEL)
+ {
+ mThumbnailUUID = i->second.asUUID();
+ continue;
+ }
+
+ if (i->first == INV_PERMISSIONS_LABEL)
+ {
+ mPermissions = ll_permissions_from_sd(i->second);
+ continue;
+ }
+
+ if (i->first == INV_SALE_INFO_LABEL)
+ {
+ // Sale info used to contain next owner perm. It is now in
+ // the permissions. Thus, we read that out, and fix legacy
+ // objects. It's possible this op would fail, but it
+ // should pick up the vast majority of the tasks.
+ bool has_perm_mask = false;
+ U32 perm_mask = 0;
+ if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))
+ {
+ return false;
+ }
+ if (has_perm_mask)
+ {
+ if (perm_mask == PERM_NONE)
+ {
+ perm_mask = mPermissions.getMaskOwner();
+ }
+ // fair use fix.
+ if (!(perm_mask & PERM_COPY))
+ {
+ perm_mask |= PERM_TRANSFER;
+ }
+ mPermissions.setMaskNext(perm_mask);
+ }
+ continue;
+ }
+
+ if (i->first == INV_SHADOW_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+ cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
+ continue;
+ }
+
+ if (i->first == INV_ASSET_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_LINKED_ID_LABEL)
+ {
+ mAssetUUID = i->second;
+ continue;
+ }
+
+ if (i->first == INV_ASSET_TYPE_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isString())
+ {
+ mType = LLAssetType::lookup(label.asString().c_str());
+ }
+ else if (label.isInteger())
+ {
+ S8 type = (U8) label.asInteger();
+ mType = static_cast<LLAssetType::EType>(type);
+ }
+ continue;
+ }
+
+ if (i->first == INV_INVENTORY_TYPE_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isString())
+ {
+ mInventoryType = LLInventoryType::lookup(label.asString().c_str());
+ }
+ else if (label.isInteger())
+ {
+ S8 type = (U8) label.asInteger();
+ mInventoryType = static_cast<LLInventoryType::EType>(type);
+ }
+ continue;
+ }
+
+ if (i->first == INV_FLAGS_LABEL)
+ {
+ LLSD const &label = i->second;
+ if (label.isBinary())
+ {
+ mFlags = ll_U32_from_sd(label);
+ }
+ else if (label.isInteger())
+ {
+ mFlags = label.asInteger();
+ }
+ continue;
+ }
+
+ if (i->first == INV_NAME_LABEL)
+ {
+ mName = i->second.asString();
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ continue;
+ }
+
+ if (i->first == INV_DESC_LABEL)
+ {
+ mDescription = i->second.asString();
+ LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+ continue;
+ }
+
+ if (i->first == INV_CREATION_DATE_LABEL)
+ {
+ mCreationDate = i->second.asInteger();
+ continue;
+ }
+ }
+
+ // Need to convert 1.0 simstate files to a useful inventory type
+ // and potentially deal with bad inventory tyes eg, a landmark
+ // marked as a texture.
+ if((LLInventoryType::IT_NONE == mInventoryType)
+ || !inventory_and_asset_types_match(mInventoryType, mType))
+ {
+ LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL;
+ mInventoryType = LLInventoryType::defaultForAssetType(mType);
+ }
+
+ mPermissions.initMasks(mInventoryType);
+
+ return true;
+}
+
+///----------------------------------------------------------------------------
+/// Class LLInventoryCategory
+///----------------------------------------------------------------------------
+
+LLInventoryCategory::LLInventoryCategory(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ LLFolderType::EType preferred_type,
+ const std::string& name) :
+ LLInventoryObject(uuid, parent_uuid, LLAssetType::AT_CATEGORY, name),
+ mPreferredType(preferred_type)
+{
+}
+
+LLInventoryCategory::LLInventoryCategory() :
+ mPreferredType(LLFolderType::FT_NONE)
+{
+ mType = LLAssetType::AT_CATEGORY;
+}
+
+LLInventoryCategory::LLInventoryCategory(const LLInventoryCategory* other) :
+ LLInventoryObject()
+{
+ copyCategory(other);
+}
+
+LLInventoryCategory::~LLInventoryCategory()
+{
+}
+
+// virtual
+void LLInventoryCategory::copyCategory(const LLInventoryCategory* other)
+{
+ copyObject(other);
+ mPreferredType = other->mPreferredType;
+}
+
+LLFolderType::EType LLInventoryCategory::getPreferredType() const
+{
+ return mPreferredType;
+}
+
+void LLInventoryCategory::setPreferredType(LLFolderType::EType type)
+{
+ mPreferredType = type;
+}
+
+LLSD LLInventoryCategory::asLLSD() const
+{
+ LLSD sd = LLSD();
+ sd[INV_ITEM_ID_LABEL] = mUUID;
+ sd[INV_PARENT_ID_LABEL] = mParentUUID;
+ S8 type = static_cast<S8>(mPreferredType);
+ sd[INV_ASSET_TYPE_LABEL] = type;
+ sd[INV_NAME_LABEL] = mName;
+
+ if (mThumbnailUUID.notNull())
+ {
+ sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
+ }
+
+ return sd;
+}
+
+LLSD LLInventoryCategory::asAISCreateCatLLSD() const
+{
+ LLSD sd = LLSD();
+ sd[INV_FOLDER_ID_LABEL_WS] = mUUID;
+ sd[INV_PARENT_ID_LABEL] = mParentUUID;
+ S8 type = static_cast<S8>(mPreferredType);
+ sd[INV_ASSET_TYPE_LABEL_WS] = type;
+ sd[INV_NAME_LABEL] = mName;
+ if (mThumbnailUUID.notNull())
+ {
+ sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
+ }
+
+ return sd;
+}
+
+
+// virtual
+void LLInventoryCategory::packMessage(LLMessageSystem* msg) const
+{
+ msg->addUUIDFast(_PREHASH_FolderID, mUUID);
+ msg->addUUIDFast(_PREHASH_ParentID, mParentUUID);
+ S8 type = static_cast<S8>(mPreferredType);
+ msg->addS8Fast(_PREHASH_Type, type);
+ msg->addStringFast(_PREHASH_Name, mName);
+}
+
+bool LLInventoryCategory::fromLLSD(const LLSD& sd)
+{
+ std::string w;
+
+ w = INV_FOLDER_ID_LABEL_WS;
+ if (sd.has(w))
+ {
+ mUUID = sd[w];
+ }
+ w = INV_PARENT_ID_LABEL;
+ if (sd.has(w))
+ {
+ mParentUUID = sd[w];
+ }
+ mThumbnailUUID.setNull();
+ w = INV_THUMBNAIL_LABEL;
+ if (sd.has(w))
+ {
+ const LLSD &thumbnail_map = sd[w];
+ w = INV_ASSET_ID_LABEL;
+ if (thumbnail_map.has(w))
+ {
+ mThumbnailUUID = thumbnail_map[w];
+ }
+ }
+ else
+ {
+ w = INV_THUMBNAIL_ID_LABEL;
+ if (sd.has(w))
+ {
+ mThumbnailUUID = sd[w];
+ }
+ }
+ w = INV_ASSET_TYPE_LABEL;
+ if (sd.has(w))
+ {
+ S8 type = (U8)sd[w].asInteger();
+ mPreferredType = static_cast<LLFolderType::EType>(type);
+ }
+ w = INV_ASSET_TYPE_LABEL_WS;
+ if (sd.has(w))
+ {
+ S8 type = (U8)sd[w].asInteger();
+ mPreferredType = static_cast<LLFolderType::EType>(type);
+ }
+
+ w = INV_NAME_LABEL;
+ if (sd.has(w))
+ {
+ mName = sd[w].asString();
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ }
+ return true;
+}
+
+// virtual
+void LLInventoryCategory::unpackMessage(LLMessageSystem* msg,
+ const char* block,
+ S32 block_num)
+{
+ msg->getUUIDFast(block, _PREHASH_FolderID, mUUID, block_num);
+ msg->getUUIDFast(block, _PREHASH_ParentID, mParentUUID, block_num);
+ S8 type;
+ msg->getS8Fast(block, _PREHASH_Type, type, block_num);
+ mPreferredType = static_cast<LLFolderType::EType>(type);
+ msg->getStringFast(block, _PREHASH_Name, mName, block_num);
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+}
+
+// virtual
+bool LLInventoryCategory::importLegacyStream(std::istream& input_stream)
+{
+ // *NOTE: Changing the buffer size will require changing the scanf
+ // calls below.
+ char buffer[MAX_STRING]; /* Flawfinder: ignore */
+ char keyword[MAX_STRING]; /* Flawfinder: ignore */
+ char valuestr[MAX_STRING]; /* Flawfinder: ignore */
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+ while(input_stream.good())
+ {
+ input_stream.getline(buffer, MAX_STRING);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s %254s",
+ keyword, valuestr);
+ if(0 == strcmp("{",keyword))
+ {
+ continue;
+ }
+ if(0 == strcmp("}", keyword))
+ {
+ break;
+ }
+ else if(0 == strcmp("cat_id", keyword))
+ {
+ mUUID.set(valuestr);
+ }
+ else if(0 == strcmp("parent_id", keyword))
+ {
+ mParentUUID.set(valuestr);
+ }
+ else if(0 == strcmp("type", keyword))
+ {
+ mType = LLAssetType::lookup(valuestr);
+ }
+ else if(0 == strcmp("pref_type", keyword))
+ {
+ mPreferredType = LLFolderType::lookup(valuestr);
+ }
+ else if(0 == strcmp("name", keyword))
+ {
+ //strcpy(valuestr, buffer + strlen(keyword) + 3);
+ // *NOTE: Not ANSI C, but widely supported.
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s %254[^|]",
+ keyword, valuestr);
+ mName.assign(valuestr);
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ }
+ else if (0 == strcmp("metadata", keyword))
+ {
+ LLSD metadata;
+ if (strncmp("<llsd>", valuestr, 6) == 0)
+ {
+ std::istringstream stream(valuestr);
+ LLSDSerialize::fromXML(metadata, stream);
+ }
+ else
+ {
+ // next line likely contains metadata, but at the moment is not supported
+ // can do something like:
+ // LLSDSerialize::fromNotation(metadata, input_stream, -1);
+ }
+
+ if (metadata.has("thumbnail"))
+ {
+ const LLSD& thumbnail = metadata["thumbnail"];
+ if (thumbnail.has("asset_id"))
+ {
+ setThumbnailUUID(thumbnail["asset_id"].asUUID());
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else
+ {
+ setThumbnailUUID(LLUUID::null);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword '" << keyword
+ << "' in inventory import category " << mUUID << LL_ENDL;
+ }
+ }
+ return true;
+}
+
+bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool) const
+{
+ std::string uuid_str;
+ output_stream << "\tinv_category\t0\n\t{\n";
+ mUUID.toString(uuid_str);
+ output_stream << "\t\tcat_id\t" << uuid_str << "\n";
+ mParentUUID.toString(uuid_str);
+ output_stream << "\t\tparent_id\t" << uuid_str << "\n";
+ output_stream << "\t\ttype\t" << LLAssetType::lookup(mType) << "\n";
+ output_stream << "\t\tpref_type\t" << LLFolderType::lookup(mPreferredType) << "\n";
+ output_stream << "\t\tname\t" << mName.c_str() << "|\n";
+ if (mThumbnailUUID.notNull())
+ {
+ // Only up to 255 chars
+ LLSD metadata;
+ metadata["thumbnail"] = LLSD().with("asset_id", mThumbnailUUID);
+ output_stream << "\t\tmetadata\t";
+ LLSDSerialize::toXML(metadata, output_stream);
+ output_stream << "|\n";
+ }
+ output_stream << "\t}\n";
+ return true;
+}
+
+LLSD LLInventoryCategory::exportLLSD() const
+{
+ LLSD cat_data;
+ cat_data[INV_FOLDER_ID_LABEL] = mUUID;
+ cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
+ cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
+ cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
+ cat_data[INV_NAME_LABEL] = mName;
+
+ if (mThumbnailUUID.notNull())
+ {
+ cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
+ }
+
+ return cat_data;
+}
+
+bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
+{
+ if (cat_data.has(INV_FOLDER_ID_LABEL))
+ {
+ setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
+ }
+ if (cat_data.has(INV_PARENT_ID_LABEL))
+ {
+ setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
+ }
+ if (cat_data.has(INV_ASSET_TYPE_LABEL))
+ {
+ setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
+ }
+ if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
+ {
+ setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
+ }
+ if (cat_data.has(INV_THUMBNAIL_LABEL))
+ {
+ LLUUID thumbnail_uuid;
+ const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL];
+ if (thumbnail_data.has(INV_ASSET_ID_LABEL))
+ {
+ thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
+ }
+ setThumbnailUUID(thumbnail_uuid);
+ }
+ if (cat_data.has(INV_NAME_LABEL))
+ {
+ mName = cat_data[INV_NAME_LABEL].asString();
+ LLStringUtil::replaceNonstandardASCII(mName, ' ');
+ LLStringUtil::replaceChar(mName, '|', ' ');
+ }
+
+ return true;
+}
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+
+LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)
+{
+ LLSD rv;
+ if(item.isNull()) return rv;
+ if (item->getType() == LLAssetType::AT_NONE)
+ {
+ LL_WARNS() << "ll_create_sd_from_inventory_item() for item with AT_NONE"
+ << LL_ENDL;
+ return rv;
+ }
+ rv[INV_ITEM_ID_LABEL] = item->getUUID();
+ rv[INV_PARENT_ID_LABEL] = item->getParentUUID();
+ rv[INV_NAME_LABEL] = item->getName();
+ rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(item->getType());
+ rv[INV_ASSET_ID_LABEL] = item->getAssetUUID();
+ rv[INV_DESC_LABEL] = item->getDescription();
+ rv[INV_SALE_INFO_LABEL] = ll_create_sd_from_sale_info(item->getSaleInfo());
+ rv[INV_PERMISSIONS_LABEL] =
+ ll_create_sd_from_permissions(item->getPermissions());
+ rv[INV_INVENTORY_TYPE_LABEL] =
+ LLInventoryType::lookup(item->getInventoryType());
+ rv[INV_FLAGS_LABEL] = (S32)item->getFlags();
+ rv[INV_CREATION_DATE_LABEL] = (S32)item->getCreationDate();
+ return rv;
+}
+
+LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat)
+{
+ LLSD rv;
+ if(cat.isNull()) return rv;
+ if (cat->getType() == LLAssetType::AT_NONE)
+ {
+ LL_WARNS() << "ll_create_sd_from_inventory_category() for cat with AT_NONE"
+ << LL_ENDL;
+ return rv;
+ }
+ rv[INV_FOLDER_ID_LABEL] = cat->getUUID();
+ rv[INV_PARENT_ID_LABEL] = cat->getParentUUID();
+ rv[INV_NAME_LABEL] = cat->getName();
+ rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(cat->getType());
+ if(LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
+ {
+ rv[INV_PREFERRED_TYPE_LABEL] =
+ LLFolderType::lookup(cat->getPreferredType()).c_str();
+ }
+ return rv;
+}
+
+LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat)
+{
+ LLPointer<LLInventoryCategory> rv = new LLInventoryCategory;
+ rv->setUUID(sd_cat[INV_FOLDER_ID_LABEL].asUUID());
+ rv->setParent(sd_cat[INV_PARENT_ID_LABEL].asUUID());
+ rv->rename(sd_cat[INV_NAME_LABEL].asString());
+ rv->setType(
+ LLAssetType::lookup(sd_cat[INV_ASSET_TYPE_LABEL].asString()));
+ rv->setPreferredType(
+ LLFolderType::lookup(
+ sd_cat[INV_PREFERRED_TYPE_LABEL].asString()));
+ return rv;
+}
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index 929a8ef555..38ce3197e9 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -1,293 +1,293 @@ -/** - * @file llinventory.h - * @brief LLInventoryItem and LLInventoryCategory class declaration. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLINVENTORY_H -#define LL_LLINVENTORY_H - -#include "llfoldertype.h" -#include "llinventorytype.h" -#include "llpermissions.h" -#include "llrefcount.h" -#include "llsaleinfo.h" -#include "llsd.h" -#include "lluuid.h" -#include "lltrace.h" - -class LLMessageSystem; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInventoryObject -// -// Base class for anything in the user's inventory. Handles the common code -// between items and categories. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryObject : public LLRefCount -{ -public: - typedef std::list<LLPointer<LLInventoryObject> > object_list_t; - typedef std::list<LLConstPointer<LLInventoryObject> > const_object_list_t; - - //-------------------------------------------------------------------- - // Initialization - //-------------------------------------------------------------------- -public: - LLInventoryObject(); - LLInventoryObject(const LLUUID& uuid, - const LLUUID& parent_uuid, - LLAssetType::EType type, - const std::string& name); - void copyObject(const LLInventoryObject* other); // LLRefCount requires custom copy -protected: - virtual ~LLInventoryObject(); - - //-------------------------------------------------------------------- - // Accessors - //-------------------------------------------------------------------- -public: - virtual const LLUUID& getUUID() const; // inventoryID that this item points to - virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID - const LLUUID& getParentUUID() const; - virtual const LLUUID& getThumbnailUUID() const; - virtual const std::string& getName() const; - virtual LLAssetType::EType getType() const; - LLAssetType::EType getActualType() const; // bypasses indirection for linked items - bool getIsLinkType() const; - virtual time_t getCreationDate() const; - - //-------------------------------------------------------------------- - // Mutators - // Will not call updateServer - //-------------------------------------------------------------------- -public: - void setUUID(const LLUUID& new_uuid); - virtual void rename(const std::string& new_name); - void setParent(const LLUUID& new_parent); - virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid); - void setType(LLAssetType::EType type); - virtual void setCreationDate(time_t creation_date_utc); // only stored for items - - // in place correction for inventory name string - static void correctInventoryName(std::string& name); - - //-------------------------------------------------------------------- - // File Support - // Implemented here so that a minimal information set can be transmitted - // between simulator and viewer. - //-------------------------------------------------------------------- - - virtual bool importLegacyStream(std::istream& input_stream); - virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const; - - virtual void updateParentOnServer(bool) const; - virtual void updateServer(bool) const; - - //-------------------------------------------------------------------- - // Member Variables - //-------------------------------------------------------------------- -protected: - LLUUID mUUID; - LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL. - LLUUID mThumbnailUUID; - LLAssetType::EType mType; - std::string mName; - time_t mCreationDate; // seconds from 1/1/1970, UTC -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInventoryItem -// -// An item in the current user's inventory. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryItem : public LLInventoryObject -{ -public: - typedef std::vector<LLPointer<LLInventoryItem> > item_array_t; - - //-------------------------------------------------------------------- - // Initialization - //-------------------------------------------------------------------- -public: - LLInventoryItem(const LLUUID& uuid, - const LLUUID& parent_uuid, - const LLPermissions& permissions, - const LLUUID& asset_uuid, - LLAssetType::EType type, - LLInventoryType::EType inv_type, - const std::string& name, - const std::string& desc, - const LLSaleInfo& sale_info, - U32 flags, - S32 creation_date_utc); - LLInventoryItem(); - // Create a copy of an inventory item from a pointer to another item - // Note: Because InventoryItems are ref counted, reference copy (a = b) - // is prohibited - LLInventoryItem(const LLInventoryItem* other); - virtual void copyItem(const LLInventoryItem* other); // LLRefCount requires custom copy - void generateUUID() { mUUID.generate(); } -protected: - ~LLInventoryItem(); // ref counted - - //-------------------------------------------------------------------- - // Accessors - //-------------------------------------------------------------------- -public: - virtual const LLUUID& getLinkedUUID() const; - virtual const LLPermissions& getPermissions() const; - virtual const LLUUID& getCreatorUUID() const; - virtual const LLUUID& getAssetUUID() const; - virtual const std::string& getDescription() const; - virtual const std::string& getActualDescription() const; // Does not follow links - virtual const LLSaleInfo& getSaleInfo() const; - virtual LLInventoryType::EType getInventoryType() const; - virtual U32 getFlags() const; - virtual time_t getCreationDate() const; - virtual U32 getCRC32() const; // really more of a checksum. - - //-------------------------------------------------------------------- - // Mutators - // Will not call updateServer and will never fail - // (though it may correct to sane values) - //-------------------------------------------------------------------- -public: - void setAssetUUID(const LLUUID& asset_id); - static void correctInventoryDescription(std::string& name); - void setDescription(const std::string& new_desc); - void setSaleInfo(const LLSaleInfo& sale_info); - void setPermissions(const LLPermissions& perm); - void setInventoryType(LLInventoryType::EType inv_type); - void setFlags(U32 flags); - void setCreator(const LLUUID& creator); // only used for calling cards - - // Check for changes in permissions masks and sale info - // and set the corresponding bits in mFlags. - void accumulatePermissionSlamBits(const LLInventoryItem& old_item); - - // Put this inventory item onto the current outgoing mesage. - // Assumes you have already called nextBlock(). - virtual void packMessage(LLMessageSystem* msg) const; - - // Returns true if the inventory item came through the network correctly. - // Uses a simple crc check which is defeatable, but we want to detect - // network mangling somehow. - virtual bool unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); - - //-------------------------------------------------------------------- - // File Support - //-------------------------------------------------------------------- -public: - virtual bool importLegacyStream(std::istream& input_stream); - virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const; - - //-------------------------------------------------------------------- - // Helper Functions - //-------------------------------------------------------------------- -public: - LLSD asLLSD() const; - void asLLSD( LLSD& sd ) const; - bool fromLLSD(const LLSD& sd, bool is_new = true); - - //-------------------------------------------------------------------- - // Member Variables - //-------------------------------------------------------------------- -protected: - LLPermissions mPermissions; - LLUUID mAssetUUID; - std::string mDescription; - LLSaleInfo mSaleInfo; - LLInventoryType::EType mInventoryType; - U32 mFlags; -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLInventoryCategory -// -// A category/folder of inventory items. Users come with a set of default -// categories, and can create new ones as needed. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLInventoryCategory : public LLInventoryObject -{ -public: - typedef std::vector<LLPointer<LLInventoryCategory> > cat_array_t; - - //-------------------------------------------------------------------- - // Initialization - //-------------------------------------------------------------------- -public: - LLInventoryCategory(const LLUUID& uuid, const LLUUID& parent_uuid, - LLFolderType::EType preferred_type, - const std::string& name); - LLInventoryCategory(); - LLInventoryCategory(const LLInventoryCategory* other); - void copyCategory(const LLInventoryCategory* other); // LLRefCount requires custom copy -protected: - virtual ~LLInventoryCategory(); - - //-------------------------------------------------------------------- - // Accessors And Mutators - //-------------------------------------------------------------------- -public: - LLFolderType::EType getPreferredType() const; - void setPreferredType(LLFolderType::EType type); - LLSD asLLSD() const; - LLSD asAISCreateCatLLSD() const; - bool fromLLSD(const LLSD& sd); - - //-------------------------------------------------------------------- - // Messaging - //-------------------------------------------------------------------- -public: - virtual void packMessage(LLMessageSystem* msg) const; - virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); - - //-------------------------------------------------------------------- - // File Support - //-------------------------------------------------------------------- -public: - virtual bool importLegacyStream(std::istream& input_stream); - virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const; - - LLSD exportLLSD() const; - bool importLLSD(const LLSD& cat_data); - //-------------------------------------------------------------------- - // Member Variables - //-------------------------------------------------------------------- -protected: - LLFolderType::EType mPreferredType; // Type that this category was "meant" to hold (although it may hold any type). -}; - - -//----------------------------------------------------------------------------- -// Convertors -// -// These functions convert between structured data and an inventory -// item, appropriate for serialization. -//----------------------------------------------------------------------------- -LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item); -LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat); -LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat); - -#endif // LL_LLINVENTORY_H +/**
+ * @file llinventory.h
+ * @brief LLInventoryItem and LLInventoryCategory class declaration.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORY_H
+#define LL_LLINVENTORY_H
+
+#include "llfoldertype.h"
+#include "llinventorytype.h"
+#include "llpermissions.h"
+#include "llrefcount.h"
+#include "llsaleinfo.h"
+#include "llsd.h"
+#include "lluuid.h"
+#include "lltrace.h"
+
+class LLMessageSystem;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryObject
+//
+// Base class for anything in the user's inventory. Handles the common code
+// between items and categories.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryObject : public LLRefCount
+{
+public:
+ typedef std::list<LLPointer<LLInventoryObject> > object_list_t;
+ typedef std::list<LLConstPointer<LLInventoryObject> > const_object_list_t;
+
+ //--------------------------------------------------------------------
+ // Initialization
+ //--------------------------------------------------------------------
+public:
+ LLInventoryObject();
+ LLInventoryObject(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ LLAssetType::EType type,
+ const std::string& name);
+ void copyObject(const LLInventoryObject* other); // LLRefCount requires custom copy
+protected:
+ virtual ~LLInventoryObject();
+
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ virtual const LLUUID& getUUID() const; // inventoryID that this item points to
+ virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID
+ const LLUUID& getParentUUID() const;
+ virtual const LLUUID& getThumbnailUUID() const;
+ virtual const std::string& getName() const;
+ virtual LLAssetType::EType getType() const;
+ LLAssetType::EType getActualType() const; // bypasses indirection for linked items
+ bool getIsLinkType() const;
+ virtual time_t getCreationDate() const;
+
+ //--------------------------------------------------------------------
+ // Mutators
+ // Will not call updateServer
+ //--------------------------------------------------------------------
+public:
+ void setUUID(const LLUUID& new_uuid);
+ virtual void rename(const std::string& new_name);
+ void setParent(const LLUUID& new_parent);
+ virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid);
+ void setType(LLAssetType::EType type);
+ virtual void setCreationDate(time_t creation_date_utc); // only stored for items
+
+ // in place correction for inventory name string
+ static void correctInventoryName(std::string& name);
+
+ //--------------------------------------------------------------------
+ // File Support
+ // Implemented here so that a minimal information set can be transmitted
+ // between simulator and viewer.
+ //--------------------------------------------------------------------
+
+ virtual bool importLegacyStream(std::istream& input_stream);
+ virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
+
+ virtual void updateParentOnServer(bool) const;
+ virtual void updateServer(bool) const;
+
+ //--------------------------------------------------------------------
+ // Member Variables
+ //--------------------------------------------------------------------
+protected:
+ LLUUID mUUID;
+ LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL.
+ LLUUID mThumbnailUUID;
+ LLAssetType::EType mType;
+ std::string mName;
+ time_t mCreationDate; // seconds from 1/1/1970, UTC
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryItem
+//
+// An item in the current user's inventory.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryItem : public LLInventoryObject
+{
+public:
+ typedef std::vector<LLPointer<LLInventoryItem> > item_array_t;
+
+ //--------------------------------------------------------------------
+ // Initialization
+ //--------------------------------------------------------------------
+public:
+ LLInventoryItem(const LLUUID& uuid,
+ const LLUUID& parent_uuid,
+ const LLPermissions& permissions,
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ LLInventoryType::EType inv_type,
+ const std::string& name,
+ const std::string& desc,
+ const LLSaleInfo& sale_info,
+ U32 flags,
+ S32 creation_date_utc);
+ LLInventoryItem();
+ // Create a copy of an inventory item from a pointer to another item
+ // Note: Because InventoryItems are ref counted, reference copy (a = b)
+ // is prohibited
+ LLInventoryItem(const LLInventoryItem* other);
+ virtual void copyItem(const LLInventoryItem* other); // LLRefCount requires custom copy
+ void generateUUID() { mUUID.generate(); }
+protected:
+ ~LLInventoryItem(); // ref counted
+
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ virtual const LLUUID& getLinkedUUID() const;
+ virtual const LLPermissions& getPermissions() const;
+ virtual const LLUUID& getCreatorUUID() const;
+ virtual const LLUUID& getAssetUUID() const;
+ virtual const std::string& getDescription() const;
+ virtual const std::string& getActualDescription() const; // Does not follow links
+ virtual const LLSaleInfo& getSaleInfo() const;
+ virtual LLInventoryType::EType getInventoryType() const;
+ virtual U32 getFlags() const;
+ virtual time_t getCreationDate() const;
+ virtual U32 getCRC32() const; // really more of a checksum.
+
+ //--------------------------------------------------------------------
+ // Mutators
+ // Will not call updateServer and will never fail
+ // (though it may correct to sane values)
+ //--------------------------------------------------------------------
+public:
+ void setAssetUUID(const LLUUID& asset_id);
+ static void correctInventoryDescription(std::string& name);
+ void setDescription(const std::string& new_desc);
+ void setSaleInfo(const LLSaleInfo& sale_info);
+ void setPermissions(const LLPermissions& perm);
+ void setInventoryType(LLInventoryType::EType inv_type);
+ void setFlags(U32 flags);
+ void setCreator(const LLUUID& creator); // only used for calling cards
+
+ // Check for changes in permissions masks and sale info
+ // and set the corresponding bits in mFlags.
+ void accumulatePermissionSlamBits(const LLInventoryItem& old_item);
+
+ // Put this inventory item onto the current outgoing mesage.
+ // Assumes you have already called nextBlock().
+ virtual void packMessage(LLMessageSystem* msg) const;
+
+ // Returns true if the inventory item came through the network correctly.
+ // Uses a simple crc check which is defeatable, but we want to detect
+ // network mangling somehow.
+ virtual bool unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
+
+ //--------------------------------------------------------------------
+ // File Support
+ //--------------------------------------------------------------------
+public:
+ virtual bool importLegacyStream(std::istream& input_stream);
+ virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
+
+ //--------------------------------------------------------------------
+ // Helper Functions
+ //--------------------------------------------------------------------
+public:
+ LLSD asLLSD() const;
+ void asLLSD( LLSD& sd ) const;
+ bool fromLLSD(const LLSD& sd, bool is_new = true);
+
+ //--------------------------------------------------------------------
+ // Member Variables
+ //--------------------------------------------------------------------
+protected:
+ LLPermissions mPermissions;
+ LLUUID mAssetUUID;
+ std::string mDescription;
+ LLSaleInfo mSaleInfo;
+ LLInventoryType::EType mInventoryType;
+ U32 mFlags;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLInventoryCategory
+//
+// A category/folder of inventory items. Users come with a set of default
+// categories, and can create new ones as needed.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLInventoryCategory : public LLInventoryObject
+{
+public:
+ typedef std::vector<LLPointer<LLInventoryCategory> > cat_array_t;
+
+ //--------------------------------------------------------------------
+ // Initialization
+ //--------------------------------------------------------------------
+public:
+ LLInventoryCategory(const LLUUID& uuid, const LLUUID& parent_uuid,
+ LLFolderType::EType preferred_type,
+ const std::string& name);
+ LLInventoryCategory();
+ LLInventoryCategory(const LLInventoryCategory* other);
+ void copyCategory(const LLInventoryCategory* other); // LLRefCount requires custom copy
+protected:
+ virtual ~LLInventoryCategory();
+
+ //--------------------------------------------------------------------
+ // Accessors And Mutators
+ //--------------------------------------------------------------------
+public:
+ LLFolderType::EType getPreferredType() const;
+ void setPreferredType(LLFolderType::EType type);
+ LLSD asLLSD() const;
+ LLSD asAISCreateCatLLSD() const;
+ bool fromLLSD(const LLSD& sd);
+
+ //--------------------------------------------------------------------
+ // Messaging
+ //--------------------------------------------------------------------
+public:
+ virtual void packMessage(LLMessageSystem* msg) const;
+ virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
+
+ //--------------------------------------------------------------------
+ // File Support
+ //--------------------------------------------------------------------
+public:
+ virtual bool importLegacyStream(std::istream& input_stream);
+ virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
+
+ LLSD exportLLSD() const;
+ bool importLLSD(const LLSD& cat_data);
+ //--------------------------------------------------------------------
+ // Member Variables
+ //--------------------------------------------------------------------
+protected:
+ LLFolderType::EType mPreferredType; // Type that this category was "meant" to hold (although it may hold any type).
+};
+
+
+//-----------------------------------------------------------------------------
+// Convertors
+//
+// These functions convert between structured data and an inventory
+// item, appropriate for serialization.
+//-----------------------------------------------------------------------------
+LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
+LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat);
+LLPointer<LLInventoryCategory> ll_create_category_from_sd(const LLSD& sd_cat);
+
+#endif // LL_LLINVENTORY_H
diff --git a/indra/llinventory/llinventorydefines.cpp b/indra/llinventory/llinventorydefines.cpp index 575331a263..e05e89f549 100644 --- a/indra/llinventory/llinventorydefines.cpp +++ b/indra/llinventory/llinventorydefines.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llinventorydefines.cpp * @brief Implementation of the inventory defines. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/llinventory/llinventorydefines.h b/indra/llinventory/llinventorydefines.h index 54562673f3..8e7bd87ac4 100644 --- a/indra/llinventory/llinventorydefines.h +++ b/indra/llinventory/llinventorydefines.h @@ -1,25 +1,25 @@ -/** +/** * @file llinventorydefines.h * @brief LLInventoryDefines * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,7 +34,7 @@ extern const U8 TASK_INVENTORY_ASSET_KEY; // Max inventory buffer size (for use in packBinaryBucket) enum { - MAX_INVENTORY_BUFFER_SIZE = 1024 + MAX_INVENTORY_BUFFER_SIZE = 1024 }; //-------------------------------------------------------------------- @@ -47,55 +47,55 @@ enum class LLInventoryItemFlags { public: - enum EType - { - II_FLAGS_NONE = 0, - - II_FLAGS_SHARED_SINGLE_REFERENCE = 0x40000000, - // The asset has only one reference in the system. If the - // inventory item is deleted, or the assetid updated, then we - // can remove the old reference. - - II_FLAGS_LANDMARK_VISITED = 1, + enum EType + { + II_FLAGS_NONE = 0, + + II_FLAGS_SHARED_SINGLE_REFERENCE = 0x40000000, + // The asset has only one reference in the system. If the + // inventory item is deleted, or the assetid updated, then we + // can remove the old reference. + + II_FLAGS_LANDMARK_VISITED = 1, + + II_FLAGS_OBJECT_SLAM_PERM = 0x100, + // Object permissions should have next owner perm be more + // restrictive on rez. We bump this into the second byte of the + // flags since the low byte is used to track attachment points. - II_FLAGS_OBJECT_SLAM_PERM = 0x100, - // Object permissions should have next owner perm be more - // restrictive on rez. We bump this into the second byte of the - // flags since the low byte is used to track attachment points. + II_FLAGS_OBJECT_SLAM_SALE = 0x1000, + // The object sale information has been changed. - II_FLAGS_OBJECT_SLAM_SALE = 0x1000, - // The object sale information has been changed. - - II_FLAGS_OBJECT_PERM_OVERWRITE_BASE = 0x010000, - II_FLAGS_OBJECT_PERM_OVERWRITE_OWNER = 0x020000, - II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP = 0x040000, - II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE = 0x080000, - II_FLAGS_OBJECT_PERM_OVERWRITE_NEXT_OWNER = 0x100000, - // Specify which permissions masks to overwrite - // upon rez. Normally, if no permissions slam (above) or - // overwrite flags are set, the asset's permissions are - // used and the inventory's permissions are ignored. If - // any of these flags are set, the inventory's permissions - // take precedence. + II_FLAGS_OBJECT_PERM_OVERWRITE_BASE = 0x010000, + II_FLAGS_OBJECT_PERM_OVERWRITE_OWNER = 0x020000, + II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP = 0x040000, + II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE = 0x080000, + II_FLAGS_OBJECT_PERM_OVERWRITE_NEXT_OWNER = 0x100000, + // Specify which permissions masks to overwrite + // upon rez. Normally, if no permissions slam (above) or + // overwrite flags are set, the asset's permissions are + // used and the inventory's permissions are ignored. If + // any of these flags are set, the inventory's permissions + // take precedence. - II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000, - // Whether a returned object is composed of multiple items. + II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000, + // Whether a returned object is composed of multiple items. - II_FLAGS_SUBTYPE_MASK = 0x0000ff, - // Some items like Wearables and settings use the low order byte - // of flags to store the sub type of the inventory item. - // see LLWearableType::EType enumeration found in newview/llwearable.h + II_FLAGS_SUBTYPE_MASK = 0x0000ff, + // Some items like Wearables and settings use the low order byte + // of flags to store the sub type of the inventory item. + // see LLWearableType::EType enumeration found in newview/llwearable.h - II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM | - II_FLAGS_OBJECT_SLAM_SALE | - II_FLAGS_OBJECT_PERM_OVERWRITE_BASE | - II_FLAGS_OBJECT_PERM_OVERWRITE_OWNER | - II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP | - II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE | - II_FLAGS_OBJECT_PERM_OVERWRITE_NEXT_OWNER), - // These bits need to be cleared whenever the asset_id is updated - // on a pre-existing inventory item (DEV-28098 and DEV-30997) - }; + II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM | + II_FLAGS_OBJECT_SLAM_SALE | + II_FLAGS_OBJECT_PERM_OVERWRITE_BASE | + II_FLAGS_OBJECT_PERM_OVERWRITE_OWNER | + II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP | + II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE | + II_FLAGS_OBJECT_PERM_OVERWRITE_NEXT_OWNER), + // These bits need to be cleared whenever the asset_id is updated + // on a pre-existing inventory item (DEV-28098 and DEV-30997) + }; }; #endif // LL_LLINVENTORYDEFINES_H diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp index bc604097da..a436a7ab95 100644 --- a/indra/llinventory/llinventorysettings.cpp +++ b/indra/llinventory/llinventorysettings.cpp @@ -65,7 +65,7 @@ class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>, void initSingleton() override; }; -LLSettingsDictionary::LLSettingsDictionary() +LLSettingsDictionary::LLSettingsDictionary() { } @@ -98,7 +98,7 @@ LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags) LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type) { const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type); - if (!entry) + if (!entry) return getIconName(ST_INVALID); return entry->mIconName; } diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index ceda2f3caf..303dd8b711 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llinventorytype.cpp * @brief Inventory item type, more specific than an asset type. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,55 +38,55 @@ static const std::string empty_string; ///---------------------------------------------------------------------------- struct InventoryEntry : public LLDictionaryEntry { - InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names - const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one. - int num_asset_types = 0, ...) - : - LLDictionaryEntry(name), - mHumanName(human_name) - { - va_list argp; - va_start(argp, num_asset_types); - // Read in local textures - for (U8 i=0; i < num_asset_types; i++) - { - LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); - mAssetTypes.push_back(t); - } - } - - const std::string mHumanName; - typedef std::vector<LLAssetType::EType> asset_vec_t; - asset_vec_t mAssetTypes; + InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names + const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one. + int num_asset_types = 0, ...) + : + LLDictionaryEntry(name), + mHumanName(human_name) + { + va_list argp; + va_start(argp, num_asset_types); + // Read in local textures + for (U8 i=0; i < num_asset_types; i++) + { + LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); + mAssetTypes.push_back(t); + } + } + + const std::string mHumanName; + typedef std::vector<LLAssetType::EType> asset_vec_t; + asset_vec_t mAssetTypes; }; class LLInventoryDictionary : public LLSingleton<LLInventoryDictionary>, - public LLDictionary<LLInventoryType::EType, InventoryEntry> + public LLDictionary<LLInventoryType::EType, InventoryEntry> { - LLSINGLETON(LLInventoryDictionary); + LLSINGLETON(LLInventoryDictionary); }; LLInventoryDictionary::LLInventoryDictionary() { - addEntry(LLInventoryType::IT_TEXTURE, new InventoryEntry("texture", "texture", 1, LLAssetType::AT_TEXTURE)); - addEntry(LLInventoryType::IT_SOUND, new InventoryEntry("sound", "sound", 1, LLAssetType::AT_SOUND)); - addEntry(LLInventoryType::IT_CALLINGCARD, new InventoryEntry("callcard", "calling card", 1, LLAssetType::AT_CALLINGCARD)); - addEntry(LLInventoryType::IT_LANDMARK, new InventoryEntry("landmark", "landmark", 1, LLAssetType::AT_LANDMARK)); - addEntry(LLInventoryType::IT_OBJECT, new InventoryEntry("object", "object", 1, LLAssetType::AT_OBJECT)); - addEntry(LLInventoryType::IT_NOTECARD, new InventoryEntry("notecard", "note card", 1, LLAssetType::AT_NOTECARD)); - addEntry(LLInventoryType::IT_CATEGORY, new InventoryEntry("category", "folder" )); - addEntry(LLInventoryType::IT_ROOT_CATEGORY, new InventoryEntry("root", "root" )); - addEntry(LLInventoryType::IT_LSL, new InventoryEntry("script", "script", 2, LLAssetType::AT_LSL_TEXT, LLAssetType::AT_LSL_BYTECODE)); - addEntry(LLInventoryType::IT_SNAPSHOT, new InventoryEntry("snapshot", "snapshot", 1, LLAssetType::AT_TEXTURE)); - addEntry(LLInventoryType::IT_ATTACHMENT, new InventoryEntry("attach", "attachment", 1, LLAssetType::AT_OBJECT)); - addEntry(LLInventoryType::IT_WEARABLE, new InventoryEntry("wearable", "wearable", 2, LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART)); - addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION)); - addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE)); - addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH)); - addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET)); - addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON)); + addEntry(LLInventoryType::IT_TEXTURE, new InventoryEntry("texture", "texture", 1, LLAssetType::AT_TEXTURE)); + addEntry(LLInventoryType::IT_SOUND, new InventoryEntry("sound", "sound", 1, LLAssetType::AT_SOUND)); + addEntry(LLInventoryType::IT_CALLINGCARD, new InventoryEntry("callcard", "calling card", 1, LLAssetType::AT_CALLINGCARD)); + addEntry(LLInventoryType::IT_LANDMARK, new InventoryEntry("landmark", "landmark", 1, LLAssetType::AT_LANDMARK)); + addEntry(LLInventoryType::IT_OBJECT, new InventoryEntry("object", "object", 1, LLAssetType::AT_OBJECT)); + addEntry(LLInventoryType::IT_NOTECARD, new InventoryEntry("notecard", "note card", 1, LLAssetType::AT_NOTECARD)); + addEntry(LLInventoryType::IT_CATEGORY, new InventoryEntry("category", "folder" )); + addEntry(LLInventoryType::IT_ROOT_CATEGORY, new InventoryEntry("root", "root" )); + addEntry(LLInventoryType::IT_LSL, new InventoryEntry("script", "script", 2, LLAssetType::AT_LSL_TEXT, LLAssetType::AT_LSL_BYTECODE)); + addEntry(LLInventoryType::IT_SNAPSHOT, new InventoryEntry("snapshot", "snapshot", 1, LLAssetType::AT_TEXTURE)); + addEntry(LLInventoryType::IT_ATTACHMENT, new InventoryEntry("attach", "attachment", 1, LLAssetType::AT_OBJECT)); + addEntry(LLInventoryType::IT_WEARABLE, new InventoryEntry("wearable", "wearable", 2, LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART)); + addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION)); + addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE)); + addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH)); + addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET)); + addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON)); addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS)); - addEntry(LLInventoryType::IT_MATERIAL, new InventoryEntry("material", "render material", 1, LLAssetType::AT_MATERIAL)); + addEntry(LLInventoryType::IT_MATERIAL, new InventoryEntry("material", "render material", 1, LLAssetType::AT_MATERIAL)); } @@ -95,64 +95,64 @@ LLInventoryDictionary::LLInventoryDictionary() static const LLInventoryType::EType DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = { - LLInventoryType::IT_TEXTURE, // 0 AT_TEXTURE - LLInventoryType::IT_SOUND, // 1 AT_SOUND - LLInventoryType::IT_CALLINGCARD, // 2 AT_CALLINGCARD - LLInventoryType::IT_LANDMARK, // 3 AT_LANDMARK - LLInventoryType::IT_LSL, // 4 AT_SCRIPT - LLInventoryType::IT_WEARABLE, // 5 AT_CLOTHING - LLInventoryType::IT_OBJECT, // 6 AT_OBJECT - LLInventoryType::IT_NOTECARD, // 7 AT_NOTECARD - LLInventoryType::IT_CATEGORY, // 8 AT_CATEGORY - LLInventoryType::IT_NONE, // 9 (null entry) - LLInventoryType::IT_LSL, // 10 AT_LSL_TEXT - LLInventoryType::IT_LSL, // 11 AT_LSL_BYTECODE - LLInventoryType::IT_TEXTURE, // 12 AT_TEXTURE_TGA - LLInventoryType::IT_WEARABLE, // 13 AT_BODYPART - LLInventoryType::IT_CATEGORY, // 14 AT_TRASH - LLInventoryType::IT_CATEGORY, // 15 AT_SNAPSHOT_CATEGORY - LLInventoryType::IT_CATEGORY, // 16 AT_LOST_AND_FOUND - LLInventoryType::IT_SOUND, // 17 AT_SOUND_WAV - LLInventoryType::IT_NONE, // 18 AT_IMAGE_TGA - LLInventoryType::IT_NONE, // 19 AT_IMAGE_JPEG - LLInventoryType::IT_ANIMATION, // 20 AT_ANIMATION - LLInventoryType::IT_GESTURE, // 21 AT_GESTURE - LLInventoryType::IT_NONE, // 22 AT_SIMSTATE - - LLInventoryType::IT_NONE, // 23 AT_LINK - LLInventoryType::IT_NONE, // 24 AT_LINK_FOLDER - - LLInventoryType::IT_NONE, // 25 AT_NONE - LLInventoryType::IT_NONE, // 26 AT_NONE - LLInventoryType::IT_NONE, // 27 AT_NONE - LLInventoryType::IT_NONE, // 28 AT_NONE - LLInventoryType::IT_NONE, // 29 AT_NONE - LLInventoryType::IT_NONE, // 30 AT_NONE - LLInventoryType::IT_NONE, // 31 AT_NONE - LLInventoryType::IT_NONE, // 32 AT_NONE - LLInventoryType::IT_NONE, // 33 AT_NONE - LLInventoryType::IT_NONE, // 34 AT_NONE - LLInventoryType::IT_NONE, // 35 AT_NONE - LLInventoryType::IT_NONE, // 36 AT_NONE - LLInventoryType::IT_NONE, // 37 AT_NONE - LLInventoryType::IT_NONE, // 38 AT_NONE - LLInventoryType::IT_NONE, // 39 AT_NONE - LLInventoryType::IT_WIDGET, // 40 AT_WIDGET - LLInventoryType::IT_NONE, // 41 AT_NONE - LLInventoryType::IT_NONE, // 42 AT_NONE - LLInventoryType::IT_NONE, // 43 AT_NONE - LLInventoryType::IT_NONE, // 44 AT_NONE - LLInventoryType::IT_PERSON, // 45 AT_PERSON - LLInventoryType::IT_NONE, // 46 AT_NONE - LLInventoryType::IT_NONE, // 47 AT_NONE - LLInventoryType::IT_NONE, // 48 AT_NONE - LLInventoryType::IT_MESH, // 49 AT_MESH - - LLInventoryType::IT_NONE, // 50 AT_RESERVED_1 - LLInventoryType::IT_NONE, // 51 AT_RESERVED_2 - LLInventoryType::IT_NONE, // 52 AT_RESERVED_3 - LLInventoryType::IT_NONE, // 53 AT_RESERVED_4 - LLInventoryType::IT_NONE, // 54 AT_RESERVED_5 + LLInventoryType::IT_TEXTURE, // 0 AT_TEXTURE + LLInventoryType::IT_SOUND, // 1 AT_SOUND + LLInventoryType::IT_CALLINGCARD, // 2 AT_CALLINGCARD + LLInventoryType::IT_LANDMARK, // 3 AT_LANDMARK + LLInventoryType::IT_LSL, // 4 AT_SCRIPT + LLInventoryType::IT_WEARABLE, // 5 AT_CLOTHING + LLInventoryType::IT_OBJECT, // 6 AT_OBJECT + LLInventoryType::IT_NOTECARD, // 7 AT_NOTECARD + LLInventoryType::IT_CATEGORY, // 8 AT_CATEGORY + LLInventoryType::IT_NONE, // 9 (null entry) + LLInventoryType::IT_LSL, // 10 AT_LSL_TEXT + LLInventoryType::IT_LSL, // 11 AT_LSL_BYTECODE + LLInventoryType::IT_TEXTURE, // 12 AT_TEXTURE_TGA + LLInventoryType::IT_WEARABLE, // 13 AT_BODYPART + LLInventoryType::IT_CATEGORY, // 14 AT_TRASH + LLInventoryType::IT_CATEGORY, // 15 AT_SNAPSHOT_CATEGORY + LLInventoryType::IT_CATEGORY, // 16 AT_LOST_AND_FOUND + LLInventoryType::IT_SOUND, // 17 AT_SOUND_WAV + LLInventoryType::IT_NONE, // 18 AT_IMAGE_TGA + LLInventoryType::IT_NONE, // 19 AT_IMAGE_JPEG + LLInventoryType::IT_ANIMATION, // 20 AT_ANIMATION + LLInventoryType::IT_GESTURE, // 21 AT_GESTURE + LLInventoryType::IT_NONE, // 22 AT_SIMSTATE + + LLInventoryType::IT_NONE, // 23 AT_LINK + LLInventoryType::IT_NONE, // 24 AT_LINK_FOLDER + + LLInventoryType::IT_NONE, // 25 AT_NONE + LLInventoryType::IT_NONE, // 26 AT_NONE + LLInventoryType::IT_NONE, // 27 AT_NONE + LLInventoryType::IT_NONE, // 28 AT_NONE + LLInventoryType::IT_NONE, // 29 AT_NONE + LLInventoryType::IT_NONE, // 30 AT_NONE + LLInventoryType::IT_NONE, // 31 AT_NONE + LLInventoryType::IT_NONE, // 32 AT_NONE + LLInventoryType::IT_NONE, // 33 AT_NONE + LLInventoryType::IT_NONE, // 34 AT_NONE + LLInventoryType::IT_NONE, // 35 AT_NONE + LLInventoryType::IT_NONE, // 36 AT_NONE + LLInventoryType::IT_NONE, // 37 AT_NONE + LLInventoryType::IT_NONE, // 38 AT_NONE + LLInventoryType::IT_NONE, // 39 AT_NONE + LLInventoryType::IT_WIDGET, // 40 AT_WIDGET + LLInventoryType::IT_NONE, // 41 AT_NONE + LLInventoryType::IT_NONE, // 42 AT_NONE + LLInventoryType::IT_NONE, // 43 AT_NONE + LLInventoryType::IT_NONE, // 44 AT_NONE + LLInventoryType::IT_PERSON, // 45 AT_PERSON + LLInventoryType::IT_NONE, // 46 AT_NONE + LLInventoryType::IT_NONE, // 47 AT_NONE + LLInventoryType::IT_NONE, // 48 AT_NONE + LLInventoryType::IT_MESH, // 49 AT_MESH + + LLInventoryType::IT_NONE, // 50 AT_RESERVED_1 + LLInventoryType::IT_NONE, // 51 AT_RESERVED_2 + LLInventoryType::IT_NONE, // 52 AT_RESERVED_3 + LLInventoryType::IT_NONE, // 53 AT_RESERVED_4 + LLInventoryType::IT_NONE, // 54 AT_RESERVED_5 LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS <- why doesnt this match the value in llassettype.h? -brad LLInventoryType::IT_MATERIAL, // 57 AT_MATERIAL @@ -161,15 +161,15 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = // static const std::string &LLInventoryType::lookup(EType type) { - const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); - if (!entry) return empty_string; - return entry->mName; + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); + if (!entry) return empty_string; + return entry->mName; } // static LLInventoryType::EType LLInventoryType::lookup(const std::string& name) { - return LLInventoryDictionary::getInstance()->lookup(name); + return LLInventoryDictionary::getInstance()->lookup(name); } // XUI:translate @@ -177,23 +177,23 @@ LLInventoryType::EType LLInventoryType::lookup(const std::string& name) // static const std::string &LLInventoryType::lookupHumanReadable(EType type) { - const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); - if (!entry) return empty_string; - return entry->mHumanName; + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(type); + if (!entry) return empty_string; + return entry->mHumanName; } // return the default inventory for the given asset type. // static LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType asset_type) { - if((asset_type >= 0) && (asset_type < LLAssetType::AT_COUNT)) - { - return DEFAULT_ASSET_FOR_INV_TYPE[S32(asset_type)]; - } - else - { - return IT_UNKNOWN; - } + if((asset_type >= 0) && (asset_type < LLAssetType::AT_COUNT)) + { + return DEFAULT_ASSET_FOR_INV_TYPE[S32(asset_type)]; + } + else + { + return IT_UNKNOWN; + } } @@ -201,14 +201,14 @@ LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType a // static bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type) { - switch(type) - { - case IT_CALLINGCARD: - case IT_LANDMARK: - return true; - default: - return false; - } + switch(type) + { + case IT_CALLINGCARD: + case IT_LANDMARK: + return true; + default: + return false; + } } // Should show permissions that apply only to objects rezed in world. @@ -218,24 +218,24 @@ bool LLInventoryType::showInWorldPermissions(LLInventoryType::EType type) } bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, - LLAssetType::EType asset_type) + LLAssetType::EType asset_type) { - // Links can be of any inventory type. - if (LLAssetType::lookupIsLinkType(asset_type)) - return true; - - const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(inventory_type); - if (!entry) return false; - - for (InventoryEntry::asset_vec_t::const_iterator iter = entry->mAssetTypes.begin(); - iter != entry->mAssetTypes.end(); - iter++) - { - const LLAssetType::EType type = (*iter); - if(type == asset_type) - { - return true; - } - } - return false; + // Links can be of any inventory type. + if (LLAssetType::lookupIsLinkType(asset_type)) + return true; + + const InventoryEntry *entry = LLInventoryDictionary::getInstance()->lookup(inventory_type); + if (!entry) return false; + + for (InventoryEntry::asset_vec_t::const_iterator iter = entry->mAssetTypes.begin(); + iter != entry->mAssetTypes.end(); + iter++) + { + const LLAssetType::EType type = (*iter); + if(type == asset_type) + { + return true; + } + } + return false; } diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index a5543814d8..fd80a0be04 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -1,25 +1,25 @@ -/** +/** * @file llinventorytype.h * @brief Inventory item type, more specific than an asset type. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,81 +38,81 @@ class LLInventoryType { public: - enum EType - { - IT_TEXTURE = 0, - IT_SOUND = 1, - IT_CALLINGCARD = 2, - IT_LANDMARK = 3, - //IT_SCRIPT = 4, - //IT_CLOTHING = 5, - IT_OBJECT = 6, - IT_NOTECARD = 7, - IT_CATEGORY = 8, - IT_ROOT_CATEGORY = 9, - IT_LSL = 10, - //IT_LSL_BYTECODE = 11, - //IT_TEXTURE_TGA = 12, - //IT_BODYPART = 13, - //IT_TRASH = 14, - IT_SNAPSHOT = 15, - //IT_LOST_AND_FOUND = 16, - IT_ATTACHMENT = 17, - IT_WEARABLE = 18, - IT_ANIMATION = 19, - IT_GESTURE = 20, - IT_MESH = 22, - IT_WIDGET = 23, - IT_PERSON = 24, + enum EType + { + IT_TEXTURE = 0, + IT_SOUND = 1, + IT_CALLINGCARD = 2, + IT_LANDMARK = 3, + //IT_SCRIPT = 4, + //IT_CLOTHING = 5, + IT_OBJECT = 6, + IT_NOTECARD = 7, + IT_CATEGORY = 8, + IT_ROOT_CATEGORY = 9, + IT_LSL = 10, + //IT_LSL_BYTECODE = 11, + //IT_TEXTURE_TGA = 12, + //IT_BODYPART = 13, + //IT_TRASH = 14, + IT_SNAPSHOT = 15, + //IT_LOST_AND_FOUND = 16, + IT_ATTACHMENT = 17, + IT_WEARABLE = 18, + IT_ANIMATION = 19, + IT_GESTURE = 20, + IT_MESH = 22, + IT_WIDGET = 23, + IT_PERSON = 24, IT_SETTINGS = 25, IT_MATERIAL = 26, - IT_COUNT = 27, - - IT_UNKNOWN = 255, - IT_NONE = -1 - }; - - enum EIconName - { - ICONNAME_TEXTURE, - ICONNAME_SOUND, - ICONNAME_CALLINGCARD_ONLINE, - ICONNAME_CALLINGCARD_OFFLINE, - ICONNAME_LANDMARK, - ICONNAME_LANDMARK_VISITED, - ICONNAME_SCRIPT, - ICONNAME_CLOTHING, - ICONNAME_OBJECT, - ICONNAME_OBJECT_MULTI, - ICONNAME_NOTECARD, - ICONNAME_BODYPART, - ICONNAME_SNAPSHOT, - - ICONNAME_BODYPART_SHAPE, - ICONNAME_BODYPART_SKIN, - ICONNAME_BODYPART_HAIR, - ICONNAME_BODYPART_EYES, - ICONNAME_CLOTHING_SHIRT, - ICONNAME_CLOTHING_PANTS, - ICONNAME_CLOTHING_SHOES, - ICONNAME_CLOTHING_SOCKS, - ICONNAME_CLOTHING_JACKET, - ICONNAME_CLOTHING_GLOVES, - ICONNAME_CLOTHING_UNDERSHIRT, - ICONNAME_CLOTHING_UNDERPANTS, - ICONNAME_CLOTHING_SKIRT, - ICONNAME_CLOTHING_ALPHA, - ICONNAME_CLOTHING_TATTOO, - ICONNAME_CLOTHING_UNIVERSAL, - - ICONNAME_ANIMATION, - ICONNAME_GESTURE, - - ICONNAME_CLOTHING_PHYSICS, - - ICONNAME_LINKITEM, - ICONNAME_LINKFOLDER, - ICONNAME_MESH, + IT_COUNT = 27, + + IT_UNKNOWN = 255, + IT_NONE = -1 + }; + + enum EIconName + { + ICONNAME_TEXTURE, + ICONNAME_SOUND, + ICONNAME_CALLINGCARD_ONLINE, + ICONNAME_CALLINGCARD_OFFLINE, + ICONNAME_LANDMARK, + ICONNAME_LANDMARK_VISITED, + ICONNAME_SCRIPT, + ICONNAME_CLOTHING, + ICONNAME_OBJECT, + ICONNAME_OBJECT_MULTI, + ICONNAME_NOTECARD, + ICONNAME_BODYPART, + ICONNAME_SNAPSHOT, + + ICONNAME_BODYPART_SHAPE, + ICONNAME_BODYPART_SKIN, + ICONNAME_BODYPART_HAIR, + ICONNAME_BODYPART_EYES, + ICONNAME_CLOTHING_SHIRT, + ICONNAME_CLOTHING_PANTS, + ICONNAME_CLOTHING_SHOES, + ICONNAME_CLOTHING_SOCKS, + ICONNAME_CLOTHING_JACKET, + ICONNAME_CLOTHING_GLOVES, + ICONNAME_CLOTHING_UNDERSHIRT, + ICONNAME_CLOTHING_UNDERPANTS, + ICONNAME_CLOTHING_SKIRT, + ICONNAME_CLOTHING_ALPHA, + ICONNAME_CLOTHING_TATTOO, + ICONNAME_CLOTHING_UNIVERSAL, + + ICONNAME_ANIMATION, + ICONNAME_GESTURE, + + ICONNAME_CLOTHING_PHYSICS, + + ICONNAME_LINKITEM, + ICONNAME_LINKFOLDER, + ICONNAME_MESH, ICONNAME_SETTINGS, ICONNAME_SETTINGS_SKY, @@ -121,37 +121,37 @@ public: ICONNAME_MATERIAL, - ICONNAME_INVALID, - ICONNAME_UNKNOWN, - ICONNAME_COUNT, - ICONNAME_NONE = -1 - }; + ICONNAME_INVALID, + ICONNAME_UNKNOWN, + ICONNAME_COUNT, + ICONNAME_NONE = -1 + }; - // machine transation between type and strings - static EType lookup(const std::string& name); - static const std::string &lookup(EType type); - // translation from a type to a human readable form. - static const std::string &lookupHumanReadable(EType type); + // machine transation between type and strings + static EType lookup(const std::string& name); + static const std::string &lookup(EType type); + // translation from a type to a human readable form. + static const std::string &lookupHumanReadable(EType type); - // return the default inventory for the given asset type. - static EType defaultForAssetType(LLAssetType::EType asset_type); + // return the default inventory for the given asset type. + static EType defaultForAssetType(LLAssetType::EType asset_type); - // true if this type cannot have restricted permissions. - static bool cannotRestrictPermissions(EType type); + // true if this type cannot have restricted permissions. + static bool cannotRestrictPermissions(EType type); static bool showInWorldPermissions(EType type); private: - // don't instantiate or derive one of these objects - LLInventoryType( void ); - ~LLInventoryType( void ); + // don't instantiate or derive one of these objects + LLInventoryType( void ); + ~LLInventoryType( void ); }; // helper function that returns true if inventory type and asset type // are potentially compatible. For example, an attachment must be an // object, but a wearable can be a bodypart or clothing asset. bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, - LLAssetType::EType asset_type); + LLAssetType::EType asset_type); #endif diff --git a/indra/llinventory/lllandmark.cpp b/indra/llinventory/lllandmark.cpp index bd7ab3c2c8..bfc0a4f511 100644 --- a/indra/llinventory/lllandmark.cpp +++ b/indra/llinventory/lllandmark.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lllandmark.cpp * @brief Landmark asset class * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,84 +37,84 @@ LLLandmark::region_map_t LLLandmark::mRegions; LLLandmark::region_callback_map_t LLLandmark::sRegionCallbackMap; LLLandmark::LLLandmark() : - mGlobalPositionKnown(false) + mGlobalPositionKnown(false) { } LLLandmark::LLLandmark(const LLVector3d& pos) : - mGlobalPositionKnown(true), - mGlobalPos( pos ) + mGlobalPositionKnown(true), + mGlobalPos( pos ) { } bool LLLandmark::getGlobalPos(LLVector3d& pos) { - if(mGlobalPositionKnown) - { - pos = mGlobalPos; - } - else if(mRegionID.notNull()) - { - F32 g_x = -1.0; - F32 g_y = -1.0; - if(mRegionID == mLocalRegion.first) - { - from_region_handle(mLocalRegion.second, &g_x, &g_y); - } - else - { - region_map_t::iterator it = mRegions.find(mRegionID); - if(it != mRegions.end()) - { - from_region_handle((*it).second.mRegionHandle, &g_x, &g_y); - } - } - if((g_x > 0.f) && (g_y > 0.f)) - { - pos.mdV[0] = g_x + mRegionPos.mV[0]; - pos.mdV[1] = g_y + mRegionPos.mV[1]; - pos.mdV[2] = mRegionPos.mV[2]; - setGlobalPos(pos); - } - } - return mGlobalPositionKnown; + if(mGlobalPositionKnown) + { + pos = mGlobalPos; + } + else if(mRegionID.notNull()) + { + F32 g_x = -1.0; + F32 g_y = -1.0; + if(mRegionID == mLocalRegion.first) + { + from_region_handle(mLocalRegion.second, &g_x, &g_y); + } + else + { + region_map_t::iterator it = mRegions.find(mRegionID); + if(it != mRegions.end()) + { + from_region_handle((*it).second.mRegionHandle, &g_x, &g_y); + } + } + if((g_x > 0.f) && (g_y > 0.f)) + { + pos.mdV[0] = g_x + mRegionPos.mV[0]; + pos.mdV[1] = g_y + mRegionPos.mV[1]; + pos.mdV[2] = mRegionPos.mV[2]; + setGlobalPos(pos); + } + } + return mGlobalPositionKnown; } void LLLandmark::setGlobalPos(const LLVector3d& pos) { - mGlobalPos = pos; - mGlobalPositionKnown = true; + mGlobalPos = pos; + mGlobalPositionKnown = true; } bool LLLandmark::getRegionID(LLUUID& region_id) { - if(mRegionID.notNull()) - { - region_id = mRegionID; - return true; - } - return false; + if(mRegionID.notNull()) + { + region_id = mRegionID; + return true; + } + return false; } LLVector3 LLLandmark::getRegionPos() const { - return mRegionPos; + return mRegionPos; } // static LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer_size) { - S32 chars_read = 0; - S32 chars_read_total = 0; - S32 count = 0; - U32 version = 0; + S32 chars_read = 0; + S32 chars_read_total = 0; + S32 count = 0; + U32 version = 0; bool bad_block = false; LLLandmark* result = NULL; - // read version - count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read ); + // read version + count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read ); chars_read_total += chars_read; if (count != 1 @@ -207,116 +207,116 @@ LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer // static void LLLandmark::registerCallbacks(LLMessageSystem* msg) { - msg->setHandlerFunc("RegionIDAndHandleReply", &processRegionIDAndHandle); + msg->setHandlerFunc("RegionIDAndHandleReply", &processRegionIDAndHandle); } // static void LLLandmark::requestRegionHandle( - LLMessageSystem* msg, - const LLHost& upstream_host, - const LLUUID& region_id, - region_handle_callback_t callback) + LLMessageSystem* msg, + const LLHost& upstream_host, + const LLUUID& region_id, + region_handle_callback_t callback) { - if(region_id.isNull()) - { - // don't bother with checking - it's 0. - LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL; - if(callback) - { - const U64 U64_ZERO = 0; - callback(region_id, U64_ZERO); - } - } - else - { - if(region_id == mLocalRegion.first) - { - LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL; - if(callback) - { - callback(region_id, mLocalRegion.second); - } - } - else - { - region_map_t::iterator it = mRegions.find(region_id); - if(it == mRegions.end()) - { - LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL; - if(callback) - { - region_callback_map_t::value_type vt(region_id, callback); - sRegionCallbackMap.insert(vt); - } - LL_DEBUGS("Landmark") << "Landmark requesting information about: " - << region_id << LL_ENDL; - msg->newMessage("RegionHandleRequest"); - msg->nextBlock("RequestBlock"); - msg->addUUID("RegionID", region_id); - msg->sendReliable(upstream_host); - } - else if(callback) - { - // we have the answer locally - just call the callack. - LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL; - callback(region_id, (*it).second.mRegionHandle); - } - } - } + if(region_id.isNull()) + { + // don't bother with checking - it's 0. + LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL; + if(callback) + { + const U64 U64_ZERO = 0; + callback(region_id, U64_ZERO); + } + } + else + { + if(region_id == mLocalRegion.first) + { + LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL; + if(callback) + { + callback(region_id, mLocalRegion.second); + } + } + else + { + region_map_t::iterator it = mRegions.find(region_id); + if(it == mRegions.end()) + { + LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL; + if(callback) + { + region_callback_map_t::value_type vt(region_id, callback); + sRegionCallbackMap.insert(vt); + } + LL_DEBUGS("Landmark") << "Landmark requesting information about: " + << region_id << LL_ENDL; + msg->newMessage("RegionHandleRequest"); + msg->nextBlock("RequestBlock"); + msg->addUUID("RegionID", region_id); + msg->sendReliable(upstream_host); + } + else if(callback) + { + // we have the answer locally - just call the callack. + LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL; + callback(region_id, (*it).second.mRegionHandle); + } + } + } - // As good a place as any to expire old entries. - expireOldEntries(); + // As good a place as any to expire old entries. + expireOldEntries(); } // static void LLLandmark::setRegionHandle(const LLUUID& region_id, U64 region_handle) { - mLocalRegion.first = region_id; - mLocalRegion.second = region_handle; + mLocalRegion.first = region_id; + mLocalRegion.second = region_handle; } // static void LLLandmark::processRegionIDAndHandle(LLMessageSystem* msg, void**) { - LLUUID region_id; - msg->getUUID("ReplyBlock", "RegionID", region_id); - mRegions.erase(region_id); - CacheInfo info; - const F32 CACHE_EXPIRY_SECONDS = 60.0f * 10.0f; // ten minutes - info.mTimer.setTimerExpirySec(CACHE_EXPIRY_SECONDS); - msg->getU64("ReplyBlock", "RegionHandle", info.mRegionHandle); - region_map_t::value_type vt(region_id, info); - mRegions.insert(vt); + LLUUID region_id; + msg->getUUID("ReplyBlock", "RegionID", region_id); + mRegions.erase(region_id); + CacheInfo info; + const F32 CACHE_EXPIRY_SECONDS = 60.0f * 10.0f; // ten minutes + info.mTimer.setTimerExpirySec(CACHE_EXPIRY_SECONDS); + msg->getU64("ReplyBlock", "RegionHandle", info.mRegionHandle); + region_map_t::value_type vt(region_id, info); + mRegions.insert(vt); #if LL_DEBUG - U32 grid_x, grid_y; - grid_from_region_handle(info.mRegionHandle, &grid_x, &grid_y); - LL_DEBUGS() << "Landmark got reply for region: " << region_id << " " - << grid_x << "," << grid_y << LL_ENDL; + U32 grid_x, grid_y; + grid_from_region_handle(info.mRegionHandle, &grid_x, &grid_y); + LL_DEBUGS() << "Landmark got reply for region: " << region_id << " " + << grid_x << "," << grid_y << LL_ENDL; #endif - // make all the callbacks here. - region_callback_map_t::iterator it; - while((it = sRegionCallbackMap.find(region_id)) != sRegionCallbackMap.end()) - { - (*it).second(region_id, info.mRegionHandle); - sRegionCallbackMap.erase(it); - } + // make all the callbacks here. + region_callback_map_t::iterator it; + while((it = sRegionCallbackMap.find(region_id)) != sRegionCallbackMap.end()) + { + (*it).second(region_id, info.mRegionHandle); + sRegionCallbackMap.erase(it); + } } // static void LLLandmark::expireOldEntries() { - for(region_map_t::iterator it = mRegions.begin(); it != mRegions.end(); ) - { - if((*it).second.mTimer.hasExpired()) - { - mRegions.erase(it++); - } - else - { - ++it; - } - } + for(region_map_t::iterator it = mRegions.begin(); it != mRegions.end(); ) + { + if((*it).second.mTimer.hasExpired()) + { + mRegions.erase(it++); + } + else + { + ++it; + } + } } diff --git a/indra/llinventory/lllandmark.h b/indra/llinventory/lllandmark.h index be34113a90..75596dc287 100644 --- a/indra/llinventory/lllandmark.h +++ b/indra/llinventory/lllandmark.h @@ -1,25 +1,25 @@ -/** +/** * @file lllandmark.h * @brief Landmark asset class * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -40,69 +40,69 @@ class LLHost; class LLLandmark { public: - // for calling back interested parties when a region handle comes back. - typedef boost::function<void(const LLUUID& region_id, const U64& region_handle)> region_handle_callback_t; + // for calling back interested parties when a region handle comes back. + typedef boost::function<void(const LLUUID& region_id, const U64& region_handle)> region_handle_callback_t; + + ~LLLandmark() {} - ~LLLandmark() {} + // returns true if the position is known. + bool getGlobalPos(LLVector3d& pos); - // returns true if the position is known. - bool getGlobalPos(LLVector3d& pos); + // setter used in conjunction if more information needs to be + // collected from the server. + void setGlobalPos(const LLVector3d& pos); - // setter used in conjunction if more information needs to be - // collected from the server. - void setGlobalPos(const LLVector3d& pos); + // return true if the region is known + bool getRegionID(LLUUID& region_id); - // return true if the region is known - bool getRegionID(LLUUID& region_id); + // return the local coordinates if known + LLVector3 getRegionPos() const; - // return the local coordinates if known - LLVector3 getRegionPos() const; + // constructs a new LLLandmark from a string + // return NULL if there's an error + static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size); - // constructs a new LLLandmark from a string - // return NULL if there's an error - static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size); + // register callbacks that this class handles + static void registerCallbacks(LLMessageSystem* msg); - // register callbacks that this class handles - static void registerCallbacks(LLMessageSystem* msg); + // request information about region_id to region_handle.Pass in a + // callback pointer which will be erase but NOT deleted after the + // callback is made. This function may call into the message + // system to get the information. + static void requestRegionHandle( + LLMessageSystem* msg, + const LLHost& upstream_host, + const LLUUID& region_id, + region_handle_callback_t callback); - // request information about region_id to region_handle.Pass in a - // callback pointer which will be erase but NOT deleted after the - // callback is made. This function may call into the message - // system to get the information. - static void requestRegionHandle( - LLMessageSystem* msg, - const LLHost& upstream_host, - const LLUUID& region_id, - region_handle_callback_t callback); + // Call this method to create a lookup for this region. This + // simplifies a lot of the code. + static void setRegionHandle(const LLUUID& region_id, U64 region_handle); - // Call this method to create a lookup for this region. This - // simplifies a lot of the code. - static void setRegionHandle(const LLUUID& region_id, U64 region_handle); - private: - LLLandmark(); - LLLandmark(const LLVector3d& pos); + LLLandmark(); + LLLandmark(const LLVector3d& pos); - static void processRegionIDAndHandle(LLMessageSystem* msg, void**); - static void expireOldEntries(); + static void processRegionIDAndHandle(LLMessageSystem* msg, void**); + static void expireOldEntries(); private: - LLUUID mRegionID; - LLVector3 mRegionPos; - bool mGlobalPositionKnown; - LLVector3d mGlobalPos; - - struct CacheInfo - { - U64 mRegionHandle; - LLFrameTimer mTimer; - }; - - static std::pair<LLUUID, U64> mLocalRegion; - typedef std::map<LLUUID, CacheInfo> region_map_t; - static region_map_t mRegions; - typedef std::multimap<LLUUID, region_handle_callback_t> region_callback_map_t; - static region_callback_map_t sRegionCallbackMap; + LLUUID mRegionID; + LLVector3 mRegionPos; + bool mGlobalPositionKnown; + LLVector3d mGlobalPos; + + struct CacheInfo + { + U64 mRegionHandle; + LLFrameTimer mTimer; + }; + + static std::pair<LLUUID, U64> mLocalRegion; + typedef std::map<LLUUID, CacheInfo> region_map_t; + static region_map_t mRegions; + typedef std::multimap<LLUUID, region_handle_callback_t> region_callback_map_t; + static region_callback_map_t sRegionCallbackMap; }; #endif diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp index 4ac5657e10..37f28272fe 100644 --- a/indra/llinventory/llnotecard.cpp +++ b/indra/llinventory/llnotecard.cpp @@ -1,289 +1,289 @@ -/** - * @file llnotecard.cpp - * @brief LLNotecard class definition - * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llnotecard.h" -#include "llstreamtools.h" - -LLNotecard::LLNotecard(S32 max_text) - : mMaxText(max_text), - mVersion(0), - mEmbeddedVersion(0) -{ -} - -LLNotecard::~LLNotecard() -{ -} - -bool LLNotecard::importEmbeddedItemsStream(std::istream& str) -{ - // Version 1 format: - // LLEmbeddedItems version 1 - // { - // count <number of entries being used and not deleted> - // { - // ext char index <index> - // <InventoryItem chunk> - // } - // } - - S32 i; - S32 count = 0; - - str >> std::ws >> "LLEmbeddedItems version" >> mEmbeddedVersion >> "\n"; - if (str.fail()) - { - LL_WARNS() << "Invalid Linden text file header" << LL_ENDL; - goto import_file_failed; - } - - if( 1 != mEmbeddedVersion ) - { - LL_WARNS() << "Invalid LLEmbeddedItems version: " << mEmbeddedVersion << LL_ENDL; - goto import_file_failed; - } - - str >> std::ws >> "{\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid Linden text file format: missing {" << LL_ENDL; - goto import_file_failed; - } - - str >> std::ws >> "count " >> count >> "\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems count" << LL_ENDL; - goto import_file_failed; - } - - if((count < 0)) - { - LL_WARNS() << "Invalid LLEmbeddedItems count value: " << count << LL_ENDL; - goto import_file_failed; - } - - for(i = 0; i < count; i++) - { - str >> std::ws >> "{\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems file format: missing {" << LL_ENDL; - goto import_file_failed; - } - - U32 index = 0; - str >> std::ws >> "ext char index " >> index >> "\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems file format: missing ext char index" << LL_ENDL; - goto import_file_failed; - } - - str >> std::ws >> "inv_item\t0\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems file format: missing inv_item" << LL_ENDL; - goto import_file_failed; - } - - LLPointer<LLInventoryItem> item = new LLInventoryItem; - if (!item->importLegacyStream(str)) - { - LL_INFOS() << "notecard import failed" << LL_ENDL; - goto import_file_failed; - } - mItems.push_back(item); - - str >> std::ws >> "}\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems file format: missing }" << LL_ENDL; - goto import_file_failed; - } - } - - str >> std::ws >> "}\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid LLEmbeddedItems file format: missing }" << LL_ENDL; - goto import_file_failed; - } - - return true; - - import_file_failed: - return false; -} - -bool LLNotecard::importStream(std::istream& str) -{ - // Version 1 format: - // Linden text version 1 - // { - // <EmbeddedItemList chunk> - // Text length - // <ASCII text; 0x80 | index = embedded item> - // } - - // Version 2 format: (NOTE: Imports identically to version 1) - // Linden text version 2 - // { - // <EmbeddedItemList chunk> - // Text length - // <UTF8 text; FIRST_EMBEDDED_CHAR + index = embedded item> - // } - - str >> std::ws >> "Linden text version " >> mVersion >> "\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid Linden text file header " << LL_ENDL; - return false; - } - - if( 1 != mVersion && 2 != mVersion) - { - LL_WARNS() << "Invalid Linden text file version: " << mVersion << LL_ENDL; - return false; - } - - str >> std::ws >> "{\n"; - if(str.fail()) - { - LL_WARNS() << "Invalid Linden text file format" << LL_ENDL; - return false; - } - - if(!importEmbeddedItemsStream(str)) - { - return false; - } - - char line_buf[STD_STRING_BUF_SIZE]; /* Flawfinder: ignore */ - str.getline(line_buf, STD_STRING_BUF_SIZE); - if(str.fail()) - { - LL_WARNS() << "Invalid Linden text length field" << LL_ENDL; - return false; - } - line_buf[STD_STRING_STR_LEN] = '\0'; - - S32 text_len = 0; - if( 1 != sscanf(line_buf, "Text length %d", &text_len) ) - { - LL_WARNS() << "Invalid Linden text length field" << LL_ENDL; - return false; - } - - if(text_len > mMaxText || text_len < 0) - { - LL_WARNS() << "Invalid Linden text length: " << text_len << LL_ENDL; - return false; - } - - bool success = true; - - char* text = new char[text_len + 1]; - fullread(str, text, text_len); - if(str.fail()) - { - LL_WARNS() << "Invalid Linden text: text shorter than text length: " << text_len << LL_ENDL; - success = false; - } - text[text_len] = '\0'; - - if(success) - { - // Actually set the text - mText = std::string(text); - } - - delete[] text; - - return success; -} - -//////////////////////////////////////////////////////////////////////////// - -bool LLNotecard::exportEmbeddedItemsStream( std::ostream& out_stream ) -{ - out_stream << "LLEmbeddedItems version 1\n"; - out_stream << "{\n"; - - out_stream << llformat("count %d\n", mItems.size() ); - - S32 idx = 0; - for (std::vector<LLPointer<LLInventoryItem> >::iterator iter = mItems.begin(); - iter != mItems.end(); ++iter) - { - LLInventoryItem* item = *iter; - if (item) - { - out_stream << "{\n"; - out_stream << llformat("ext char index %d\n", idx ); - if( !item->exportLegacyStream( out_stream ) ) - { - return false; - } - out_stream << "}\n"; - } - ++idx; - } - - out_stream << "}\n"; - - return true; -} - -bool LLNotecard::exportStream( std::ostream& out_stream ) -{ - out_stream << "Linden text version 2\n"; - out_stream << "{\n"; - - if( !exportEmbeddedItemsStream( out_stream ) ) - { - return false; - } - - out_stream << llformat("Text length %d\n", mText.length() ); - out_stream << mText; - out_stream << "}\n"; - - return true; -} - -//////////////////////////////////////////////////////////////////////////// - -void LLNotecard::setItems(const std::vector<LLPointer<LLInventoryItem> >& items) -{ - mItems = items; -} - -void LLNotecard::setText(const std::string& text) -{ - mText = text; -} +/**
+ * @file llnotecard.cpp
+ * @brief LLNotecard class definition
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llnotecard.h"
+#include "llstreamtools.h"
+
+LLNotecard::LLNotecard(S32 max_text)
+ : mMaxText(max_text),
+ mVersion(0),
+ mEmbeddedVersion(0)
+{
+}
+
+LLNotecard::~LLNotecard()
+{
+}
+
+bool LLNotecard::importEmbeddedItemsStream(std::istream& str)
+{
+ // Version 1 format:
+ // LLEmbeddedItems version 1
+ // {
+ // count <number of entries being used and not deleted>
+ // {
+ // ext char index <index>
+ // <InventoryItem chunk>
+ // }
+ // }
+
+ S32 i;
+ S32 count = 0;
+
+ str >> std::ws >> "LLEmbeddedItems version" >> mEmbeddedVersion >> "\n";
+ if (str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text file header" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ if( 1 != mEmbeddedVersion )
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems version: " << mEmbeddedVersion << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ str >> std::ws >> "{\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text file format: missing {" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ str >> std::ws >> "count " >> count >> "\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems count" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ if((count < 0))
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems count value: " << count << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ for(i = 0; i < count; i++)
+ {
+ str >> std::ws >> "{\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems file format: missing {" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ U32 index = 0;
+ str >> std::ws >> "ext char index " >> index >> "\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems file format: missing ext char index" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ str >> std::ws >> "inv_item\t0\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems file format: missing inv_item" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ LLPointer<LLInventoryItem> item = new LLInventoryItem;
+ if (!item->importLegacyStream(str))
+ {
+ LL_INFOS() << "notecard import failed" << LL_ENDL;
+ goto import_file_failed;
+ }
+ mItems.push_back(item);
+
+ str >> std::ws >> "}\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems file format: missing }" << LL_ENDL;
+ goto import_file_failed;
+ }
+ }
+
+ str >> std::ws >> "}\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid LLEmbeddedItems file format: missing }" << LL_ENDL;
+ goto import_file_failed;
+ }
+
+ return true;
+
+ import_file_failed:
+ return false;
+}
+
+bool LLNotecard::importStream(std::istream& str)
+{
+ // Version 1 format:
+ // Linden text version 1
+ // {
+ // <EmbeddedItemList chunk>
+ // Text length
+ // <ASCII text; 0x80 | index = embedded item>
+ // }
+
+ // Version 2 format: (NOTE: Imports identically to version 1)
+ // Linden text version 2
+ // {
+ // <EmbeddedItemList chunk>
+ // Text length
+ // <UTF8 text; FIRST_EMBEDDED_CHAR + index = embedded item>
+ // }
+
+ str >> std::ws >> "Linden text version " >> mVersion >> "\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text file header " << LL_ENDL;
+ return false;
+ }
+
+ if( 1 != mVersion && 2 != mVersion)
+ {
+ LL_WARNS() << "Invalid Linden text file version: " << mVersion << LL_ENDL;
+ return false;
+ }
+
+ str >> std::ws >> "{\n";
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text file format" << LL_ENDL;
+ return false;
+ }
+
+ if(!importEmbeddedItemsStream(str))
+ {
+ return false;
+ }
+
+ char line_buf[STD_STRING_BUF_SIZE]; /* Flawfinder: ignore */
+ str.getline(line_buf, STD_STRING_BUF_SIZE);
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text length field" << LL_ENDL;
+ return false;
+ }
+ line_buf[STD_STRING_STR_LEN] = '\0';
+
+ S32 text_len = 0;
+ if( 1 != sscanf(line_buf, "Text length %d", &text_len) )
+ {
+ LL_WARNS() << "Invalid Linden text length field" << LL_ENDL;
+ return false;
+ }
+
+ if(text_len > mMaxText || text_len < 0)
+ {
+ LL_WARNS() << "Invalid Linden text length: " << text_len << LL_ENDL;
+ return false;
+ }
+
+ bool success = true;
+
+ char* text = new char[text_len + 1];
+ fullread(str, text, text_len);
+ if(str.fail())
+ {
+ LL_WARNS() << "Invalid Linden text: text shorter than text length: " << text_len << LL_ENDL;
+ success = false;
+ }
+ text[text_len] = '\0';
+
+ if(success)
+ {
+ // Actually set the text
+ mText = std::string(text);
+ }
+
+ delete[] text;
+
+ return success;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+bool LLNotecard::exportEmbeddedItemsStream( std::ostream& out_stream )
+{
+ out_stream << "LLEmbeddedItems version 1\n";
+ out_stream << "{\n";
+
+ out_stream << llformat("count %d\n", mItems.size() );
+
+ S32 idx = 0;
+ for (std::vector<LLPointer<LLInventoryItem> >::iterator iter = mItems.begin();
+ iter != mItems.end(); ++iter)
+ {
+ LLInventoryItem* item = *iter;
+ if (item)
+ {
+ out_stream << "{\n";
+ out_stream << llformat("ext char index %d\n", idx );
+ if( !item->exportLegacyStream( out_stream ) )
+ {
+ return false;
+ }
+ out_stream << "}\n";
+ }
+ ++idx;
+ }
+
+ out_stream << "}\n";
+
+ return true;
+}
+
+bool LLNotecard::exportStream( std::ostream& out_stream )
+{
+ out_stream << "Linden text version 2\n";
+ out_stream << "{\n";
+
+ if( !exportEmbeddedItemsStream( out_stream ) )
+ {
+ return false;
+ }
+
+ out_stream << llformat("Text length %d\n", mText.length() );
+ out_stream << mText;
+ out_stream << "}\n";
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+void LLNotecard::setItems(const std::vector<LLPointer<LLInventoryItem> >& items)
+{
+ mItems = items;
+}
+
+void LLNotecard::setText(const std::string& text)
+{
+ mText = text;
+}
diff --git a/indra/llinventory/llnotecard.h b/indra/llinventory/llnotecard.h index d64a821b78..764157692d 100644 --- a/indra/llinventory/llnotecard.h +++ b/indra/llinventory/llnotecard.h @@ -1,25 +1,25 @@ -/** +/** * @file llnotecard.h * @brief LLNotecard class declaration * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,37 +33,37 @@ class LLNotecard { public: - /** - * @brief anonymous enumeration to set max size. - */ - enum - { - MAX_SIZE = 65536 - }; - - LLNotecard(S32 max_text = LLNotecard::MAX_SIZE); - virtual ~LLNotecard(); + /** + * @brief anonymous enumeration to set max size. + */ + enum + { + MAX_SIZE = 65536 + }; + + LLNotecard(S32 max_text = LLNotecard::MAX_SIZE); + virtual ~LLNotecard(); + + bool importStream(std::istream& str); + bool exportStream(std::ostream& str); - bool importStream(std::istream& str); - bool exportStream(std::ostream& str); + const std::vector<LLPointer<LLInventoryItem> >& getItems() const { return mItems; } + const std::string& getText() const { return mText; } + std::string& getText() { return mText; } - const std::vector<LLPointer<LLInventoryItem> >& getItems() const { return mItems; } - const std::string& getText() const { return mText; } - std::string& getText() { return mText; } + void setItems(const std::vector<LLPointer<LLInventoryItem> >& items); + void setText(const std::string& text); + S32 getVersion() { return mVersion; } + S32 getEmbeddedVersion() { return mEmbeddedVersion; } - void setItems(const std::vector<LLPointer<LLInventoryItem> >& items); - void setText(const std::string& text); - S32 getVersion() { return mVersion; } - S32 getEmbeddedVersion() { return mEmbeddedVersion; } - private: - bool importEmbeddedItemsStream(std::istream& str); - bool exportEmbeddedItemsStream(std::ostream& str); - std::vector<LLPointer<LLInventoryItem> > mItems; - std::string mText; - S32 mMaxText; - S32 mVersion; - S32 mEmbeddedVersion; + bool importEmbeddedItemsStream(std::istream& str); + bool exportEmbeddedItemsStream(std::ostream& str); + std::vector<LLPointer<LLInventoryItem> > mItems; + std::string mText; + S32 mMaxText; + S32 mVersion; + S32 mEmbeddedVersion; }; #endif /* LL_NOTECARD_H */ diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 36d9e1c900..30daf0af44 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1,1275 +1,1275 @@ -/** - * @file llparcel.cpp - * @brief A land parcel. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "indra_constants.h" -#include <iostream> - -#include "llparcel.h" -#include "llstreamtools.h" - -#include "llmath.h" -#include "llsd.h" -#include "llsdutil.h" -#include "lltransactiontypes.h" -#include "lltransactionflags.h" -#include "llsdutil_math.h" -#include "message.h" -#include "u64.h" -#include "llregionflags.h" -#include <boost/range/adaptor/map.hpp> - -static const F32 SOME_BIG_NUMBER = 1000.0f; -static const F32 SOME_BIG_NEG_NUMBER = -1000.0f; -static const std::string PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT+1] = -{ - "leased", - "lease_pending", - "abandoned", - "none" -}; - -// NOTE: Adding parcel categories also requires updating: -// * floater_about_land.xml category combobox -// * Web site "create event" tools -// DO NOT DELETE ITEMS FROM THIS LIST WITHOUT DEEPLY UNDERSTANDING WHAT YOU'RE DOING. -// -static const std::string PARCEL_CATEGORY_STRING[LLParcel::C_COUNT] = -{ - "none", - "linden", - "adult", - "arts", - "store", // "business" legacy name - "educational", - "game", // "gaming" legacy name - "gather", // "hangout" legacy name - "newcomer", - "park", - "home", // "residential" legacy name - "shopping", - "stage", - "other", - "rental" -}; -static const std::string PARCEL_CATEGORY_UI_STRING[LLParcel::C_COUNT + 1] = -{ - "None", - "Linden Location", - "Adult", - "Arts and Culture", - "Business", - "Educational", - "Gaming", - "Hangout", - "Newcomer Friendly", - "Parks and Nature", - "Residential", - "Shopping", - "Stage", - "Other", - "Rental", - "Any", // valid string for parcel searches -}; - -static const std::string PARCEL_ACTION_STRING[LLParcel::A_COUNT + 1] = -{ - "create", - "release", - "absorb", - "absorbed", - "divide", - "division", - "acquire", - "relinquish", - "confirm", - "unknown" -}; - - - -//const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action); -//LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s); -const std::string& category_to_ui_string(LLParcel::ECategory category); -LLParcel::ECategory category_ui_string_to_category(const std::string& s); - -LLParcel::LLParcel() -{ - init(LLUUID::null, true, false, false, 0, 0, 0, 0, 0, 1.f, 0); -} - - -LLParcel::LLParcel(const LLUUID &owner_id, - bool modify, bool terraform, bool damage, - time_t claim_date, S32 claim_price_per_meter, - S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus, - bool is_group_owned) -{ - init( owner_id, modify, terraform, damage, claim_date, - claim_price_per_meter, rent_price_per_meter, area, sim_object_limit, parcel_object_bonus, - is_group_owned); -} - - -// virtual -LLParcel::~LLParcel() -{ - // user list cleaned up by std::vector destructor. -} - -void LLParcel::init(const LLUUID &owner_id, - bool modify, bool terraform, bool damage, - time_t claim_date, S32 claim_price_per_meter, - S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus, - bool is_group_owned) -{ - mID.setNull(); - mOwnerID = owner_id; - mGroupOwned = is_group_owned; - mClaimDate = claim_date; - mClaimPricePerMeter = claim_price_per_meter; - mRentPricePerMeter = rent_price_per_meter; - mArea = area; - mDiscountRate = 1.0f; - mDrawDistance = 512.f; - - mUserLookAt.setVec(0.0f, 0.f, 0.f); - // Default to using the parcel's landing point, if any. - mLandingType = L_LANDING_POINT; - - // *FIX: if owner_id != null, should be owned or sale pending, - // investigate init callers. - mStatus = OS_NONE; - mCategory = C_NONE; - mAuthBuyerID.setNull(); - //mBuyerID.setNull(); - //mJoinNeighbors = 0x0; - mSaleTimerExpires.setTimerExpirySec(0); - mSaleTimerExpires.stop(); - mGraceExtension = 0; - //mExpireAction = STEA_REVERT; - //mRecordTransaction = false; - - mAuctionID = 0; - mInEscrow = false; - - mParcelFlags = PF_DEFAULT; - setParcelFlag(PF_CREATE_OBJECTS, modify); - setParcelFlag(PF_ALLOW_TERRAFORM, terraform); - setParcelFlag(PF_ALLOW_DAMAGE, damage); - - mSalePrice = 10000; - setName(LLStringUtil::null); - setDesc(LLStringUtil::null); - setMusicURL(LLStringUtil::null); - setMediaURL(LLStringUtil::null); - setMediaDesc(LLStringUtil::null); - setMediaType(LLStringUtil::null); - mMediaID.setNull(); - mMediaAutoScale = 0; - mMediaLoop = 1; - mMediaWidth = 0; - mMediaHeight = 0; - setMediaCurrentURL(LLStringUtil::null); - mMediaAllowNavigate = 1; - mMediaURLTimeout = 0.0f; - mMediaPreventCameraZoom = 0; - - mGroupID.setNull(); - - mPassPrice = PARCEL_PASS_PRICE_DEFAULT; - mPassHours = PARCEL_PASS_HOURS_DEFAULT; - - mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER); - mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER); - - mLocalID = INVALID_PARCEL_ID; - - //mSimWidePrimCorrection = 0; - setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); - setSimWideMaxPrimCapacity(0); - setSimWidePrimCount(0); - setOwnerPrimCount(0); - setGroupPrimCount(0); - setOtherPrimCount(0); - setSelectedPrimCount(0); - setTempPrimCount(0); - setCleanOtherTime(0); - setRegionPushOverride(false); - setRegionDenyAnonymousOverride(false); - setRegionDenyAgeUnverifiedOverride(false); - setParcelPrimBonus(parcel_object_bonus); - - setPreviousOwnerID(LLUUID::null); - setPreviouslyGroupOwned(false); - - setSeeAVs(true); - setAllowGroupAVSounds(true); - setAllowAnyAVSounds(true); - setHaveNewParcelLimitData(false); - - setRegionAllowEnvironmentOverride(false); - setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION); - - setObscureMOAP(false); -} - -void LLParcel::overrideOwner(const LLUUID& owner_id, bool is_group_owned) -{ - // Override with system permission (LLUUID::null) - // Overridden parcels have no group - mOwnerID = owner_id; - mGroupOwned = is_group_owned; - if(mGroupOwned) - { - mGroupID = mOwnerID; - } - else - { - mGroupID.setNull(); - } - mInEscrow = false; -} - -void LLParcel::overrideParcelFlags(U32 flags) -{ - mParcelFlags = flags; -} -void LLParcel::setName(const std::string& name) -{ - // The escaping here must match the escaping in the database - // abstraction layer. - mName = name; - LLStringFn::replace_nonprintable_in_ascii(mName, LL_UNKNOWN_CHAR); -} - -void LLParcel::setDesc(const std::string& desc) -{ - // The escaping here must match the escaping in the database - // abstraction layer. - mDesc = desc; - mDesc = rawstr_to_utf8(mDesc); -} - -void LLParcel::setMusicURL(const std::string& url) -{ - mMusicURL = url; - // The escaping here must match the escaping in the database - // abstraction layer. - // This should really filter the url in some way. Other than - // simply requiring non-printable. - LLStringFn::replace_nonprintable_in_ascii(mMusicURL, LL_UNKNOWN_CHAR); -} - -void LLParcel::setMediaURL(const std::string& url) -{ - mMediaURL = url; - // The escaping here must match the escaping in the database - // abstraction layer if it's ever added. - // This should really filter the url in some way. Other than - // simply requiring non-printable. - LLStringFn::replace_nonprintable_in_ascii(mMediaURL, LL_UNKNOWN_CHAR); -} - -void LLParcel::setMediaDesc(const std::string& desc) -{ - // The escaping here must match the escaping in the database - // abstraction layer. - mMediaDesc = desc; - mMediaDesc = rawstr_to_utf8(mMediaDesc); -} -void LLParcel::setMediaType(const std::string& type) -{ - // The escaping here must match the escaping in the database - // abstraction layer. - mMediaType = type; - mMediaType = rawstr_to_utf8(mMediaType); - - // This code attempts to preserve legacy movie functioning - if(mMediaType.empty() && ! mMediaURL.empty()) - { - setMediaType(std::string("video/vnd.secondlife.qt.legacy")); - } -} -void LLParcel::setMediaWidth(S32 width) -{ - mMediaWidth = width; -} -void LLParcel::setMediaHeight(S32 height) -{ - mMediaHeight = height; -} - -void LLParcel::setMediaCurrentURL(const std::string& url) -{ - mMediaCurrentURL = url; - // The escaping here must match the escaping in the database - // abstraction layer if it's ever added. - // This should really filter the url in some way. Other than - // simply requiring non-printable. - LLStringFn::replace_nonprintable_in_ascii(mMediaCurrentURL, LL_UNKNOWN_CHAR); - -} - -void LLParcel::setMediaURLResetTimer(F32 time) -{ - mMediaResetTimer.start(); - mMediaResetTimer.setTimerExpirySec(time); -} - -// virtual -void LLParcel::setLocalID(S32 local_id) -{ - mLocalID = local_id; -} - -void LLParcel::setAllParcelFlags(U32 flags) -{ - mParcelFlags = flags; -} - -void LLParcel::setParcelFlag(U32 flag, bool b) -{ - if (b) - { - mParcelFlags |= flag; - } - else - { - mParcelFlags &= ~flag; - } -} - - -bool LLParcel::allowModifyBy(const LLUUID &agent_id, const LLUUID &group_id) const -{ - if (agent_id == LLUUID::null) - { - // system always can enter - return true; - } - else if (isPublic()) - { - return true; - } - else if (agent_id == mOwnerID) - { - // owner can always perform operations - return true; - } - else if (mParcelFlags & PF_CREATE_OBJECTS) - { - return true; - } - else if ((mParcelFlags & PF_CREATE_GROUP_OBJECTS) - && group_id.notNull() ) - { - return (getGroupID() == group_id); - } - - return false; -} - -bool LLParcel::allowTerraformBy(const LLUUID &agent_id) const -{ - if (agent_id == LLUUID::null) - { - // system always can enter - return true; - } - else if(OS_LEASED == mStatus) - { - if(agent_id == mOwnerID) - { - // owner can modify leased land - return true; - } - else - { - // otherwise check other people - return mParcelFlags & PF_ALLOW_TERRAFORM; - } - } - else - { - return false; - } -} - - - -void LLParcel::setArea(S32 area, S32 sim_object_limit) -{ - mArea = area; - setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); -} - -void LLParcel::setDiscountRate(F32 rate) -{ - // this is to make sure that the rate is at least sane - this is - // not intended to enforce economy rules. It only enfoces that the - // rate is a scaler between 0 and 1. - mDiscountRate = llclampf(rate); -} - - -//----------------------------------------------------------- -// File input and output -//----------------------------------------------------------- - -bool LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entry) -{ - skip_to_end_of_next_keyword("{", input_stream); - while (input_stream.good()) - { - skip_comments_and_emptyspace(input_stream); - std::string line, keyword, value; - get_line(line, input_stream, MAX_STRING); - get_keyword_and_value(keyword, value, line); - - if ("}" == keyword) - { - break; - } - else if ("id" == keyword) - { - entry->mID.set( value ); - } - else if ("name" == keyword) - { - // deprecated - } - else if ("time" == keyword) - { - S32 when{}; - LLStringUtil::convertToS32(value, when); - entry->mTime = when; - } - else if ("flags" == keyword) - { - U32 setting{}; - LLStringUtil::convertToU32(value, setting); - entry->mFlags = setting; - } - else - { - LL_WARNS() << "Unknown keyword in parcel access entry section: <" - << keyword << ">" << LL_ENDL; - } - } - return input_stream.good(); -} - -// Assumes we are in a block "ParcelData" -void LLParcel::packMessage(LLMessageSystem* msg) -{ - msg->addU32Fast( _PREHASH_ParcelFlags, getParcelFlags() ); - msg->addS32Fast( _PREHASH_SalePrice, getSalePrice() ); - msg->addStringFast( _PREHASH_Name, getName() ); - msg->addStringFast( _PREHASH_Desc, getDesc() ); - msg->addStringFast( _PREHASH_MusicURL, getMusicURL() ); - msg->addStringFast( _PREHASH_MediaURL, getMediaURL() ); - msg->addU8 ( "MediaAutoScale", getMediaAutoScale () ); - msg->addUUIDFast( _PREHASH_MediaID, getMediaID() ); - msg->addUUIDFast( _PREHASH_GroupID, getGroupID() ); - msg->addS32Fast( _PREHASH_PassPrice, mPassPrice ); - msg->addF32Fast( _PREHASH_PassHours, mPassHours ); - msg->addU8Fast( _PREHASH_Category, (U8)mCategory); - msg->addUUIDFast( _PREHASH_AuthBuyerID, mAuthBuyerID); - msg->addUUIDFast( _PREHASH_SnapshotID, mSnapshotID); - msg->addVector3Fast(_PREHASH_UserLocation, mUserLocation); - msg->addVector3Fast(_PREHASH_UserLookAt, mUserLookAt); - msg->addU8Fast( _PREHASH_LandingType, (U8)mLandingType); -} - -// Assumes we are in a block "ParcelData" -void LLParcel::packMessage(LLSD& msg) -{ - // used in the viewer, the sim uses it's own packer - msg["local_id"] = getLocalID(); - msg["parcel_flags"] = ll_sd_from_U32(getParcelFlags()); - msg["sale_price"] = getSalePrice(); - msg["name"] = getName(); - msg["description"] = getDesc(); - msg["music_url"] = getMusicURL(); - msg["media_url"] = getMediaURL(); - msg["media_desc"] = getMediaDesc(); - msg["media_type"] = getMediaType(); - msg["media_width"] = getMediaWidth(); - msg["media_height"] = getMediaHeight(); - msg["auto_scale"] = getMediaAutoScale(); - msg["media_loop"] = getMediaLoop(); - msg["media_current_url"] = getMediaCurrentURL(); - msg["obscure_media"] = false; // OBSOLETE - no longer used - msg["obscure_music"] = false; // OBSOLETE - no longer used - msg["media_id"] = getMediaID(); - msg["media_allow_navigate"] = getMediaAllowNavigate(); - msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom(); - msg["media_url_timeout"] = getMediaURLTimeout(); - msg["group_id"] = getGroupID(); - msg["pass_price"] = mPassPrice; - msg["pass_hours"] = mPassHours; - msg["category"] = (U8)mCategory; - msg["auth_buyer_id"] = mAuthBuyerID; - msg["snapshot_id"] = mSnapshotID; - msg["user_location"] = ll_sd_from_vector3(mUserLocation); - msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt); - msg["landing_type"] = (U8)mLandingType; - msg["see_avs"] = (LLSD::Boolean) getSeeAVs(); - msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds(); - msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds(); - msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP(); -} - - -void LLParcel::unpackMessage(LLMessageSystem* msg) -{ - std::string buffer; - - msg->getU32Fast( _PREHASH_ParcelData,_PREHASH_ParcelFlags, mParcelFlags ); - msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_SalePrice, mSalePrice ); - msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Name, buffer ); - setName(buffer); - msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Desc, buffer ); - setDesc(buffer); - msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MusicURL, buffer ); - setMusicURL(buffer); - msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MediaURL, buffer ); - setMediaURL(buffer); - - bool see_avs = true; // All default to true for legacy server behavior - bool any_av_sounds = true; - bool group_av_sounds = true; - bool have_new_parcel_limit_data = (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_SeeAVs) > 0); // New version of server should send all 3 of these values - have_new_parcel_limit_data &= (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_AnyAVSounds) > 0); - have_new_parcel_limit_data &= (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_GroupAVSounds) > 0); - if (have_new_parcel_limit_data) - { - msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_SeeAVs, see_avs); - msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_AnyAVSounds, any_av_sounds); - msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_GroupAVSounds, group_av_sounds); - } - setSeeAVs((bool) see_avs); - setAllowAnyAVSounds((bool) any_av_sounds); - setAllowGroupAVSounds((bool) group_av_sounds); - - setHaveNewParcelLimitData(have_new_parcel_limit_data); - - // non-optimized version - msg->getU8 ( "ParcelData", "MediaAutoScale", mMediaAutoScale ); - - msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_MediaID, mMediaID ); - msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_GroupID, mGroupID ); - msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_PassPrice, mPassPrice ); - msg->getF32Fast( _PREHASH_ParcelData,_PREHASH_PassHours, mPassHours ); - U8 category; - msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_Category, category); - mCategory = (ECategory)category; - msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_AuthBuyerID, mAuthBuyerID); - msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_SnapshotID, mSnapshotID); - msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLocation, mUserLocation); - msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLookAt, mUserLookAt); - U8 landing_type; - msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_LandingType, landing_type); - mLandingType = (ELandingType)landing_type; - - // New Media Data - // Note: the message has been converted to TCP - if(msg->has("MediaData")) - { - msg->getString("MediaData", "MediaDesc", buffer); - setMediaDesc(buffer); - msg->getString("MediaData", "MediaType", buffer); - setMediaType(buffer); - msg->getS32("MediaData", "MediaWidth", mMediaWidth); - msg->getS32("MediaData", "MediaHeight", mMediaHeight); - msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop ); - // the ObscureMedia and ObscureMusic flags previously set here are no longer used - } - else - { - setMediaType(std::string("video/vnd.secondlife.qt.legacy")); - setMediaDesc(std::string("No Description available without Server Upgrade")); - mMediaLoop = true; - } - - if(msg->getNumberOfBlocks("MediaLinkSharing") > 0) - { - msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer); - setMediaCurrentURL(buffer); - msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate ); - msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom ); - msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout); - } - else - { - setMediaCurrentURL(LLStringUtil::null); - } - -} - -void LLParcel::packAccessEntries(LLMessageSystem* msg, - const std::map<LLUUID,LLAccessEntry>& list) -{ - LLAccessEntry::map::const_iterator cit = list.begin(); - LLAccessEntry::map::const_iterator end = list.end(); - - if (cit == end) - { - msg->nextBlockFast(_PREHASH_List); - msg->addUUIDFast(_PREHASH_ID, LLUUID::null ); - msg->addS32Fast(_PREHASH_Time, 0 ); - msg->addU32Fast(_PREHASH_Flags, 0 ); - return; - } - - for ( ; cit != end; ++cit) - { - const LLAccessEntry& entry = (*cit).second; - - msg->nextBlockFast(_PREHASH_List); - msg->addUUIDFast(_PREHASH_ID, entry.mID ); - msg->addS32Fast(_PREHASH_Time, entry.mTime ); - msg->addU32Fast(_PREHASH_Flags, entry.mFlags ); - } -} - - -void LLParcel::unpackAccessEntries(LLMessageSystem* msg, - std::map<LLUUID,LLAccessEntry>* list) -{ - LLUUID id; - S32 time; - U32 flags; - - S32 i; - S32 count = msg->getNumberOfBlocksFast(_PREHASH_List); - for (i = 0; i < count; i++) - { - msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i); - msg->getS32Fast( _PREHASH_List, _PREHASH_Time, time, i); - msg->getU32Fast( _PREHASH_List, _PREHASH_Flags, flags, i); - - if (id.notNull()) - { - LLAccessEntry entry; - entry.mID = id; - entry.mTime = time; - entry.mFlags = flags; - - (*list)[entry.mID] = entry; - } - } -} - - -void LLParcel::unpackExperienceEntries( LLMessageSystem* msg, U32 type ) -{ - LLUUID id; - - S32 i; - S32 count = msg->getNumberOfBlocksFast(_PREHASH_List); - for (i = 0; i < count; i++) - { - msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i); - - if (id.notNull()) - { - mExperienceKeys[id]=type; - } - } -} - - - -void LLParcel::expirePasses(S32 now) -{ - LLAccessEntry::map::iterator itor = mAccessList.begin(); - while (itor != mAccessList.end()) - { - const LLAccessEntry& entry = (*itor).second; - - if (entry.mTime != 0 && entry.mTime < now) - { - mAccessList.erase(itor++); - } - else - { - ++itor; - } - } -} - - -bool LLParcel::operator==(const LLParcel &rhs) const -{ - if (mOwnerID != rhs.mOwnerID) - return false; - - if (mParcelFlags != rhs.mParcelFlags) - return false; - - if (mClaimDate != rhs.mClaimDate) - return false; - - if (mClaimPricePerMeter != rhs.mClaimPricePerMeter) - return false; - - if (mRentPricePerMeter != rhs.mRentPricePerMeter) - return false; - - return true; -} - -// Calculate rent -S32 LLParcel::getTotalRent() const -{ - return (S32)floor(0.5f + (F32)mArea * (F32)mRentPricePerMeter * (1.0f - mDiscountRate)); -} - -F32 LLParcel::getAdjustedRentPerMeter() const -{ - return ((F32)mRentPricePerMeter * (1.0f - mDiscountRate)); -} - -LLVector3 LLParcel::getCenterpoint() const -{ - LLVector3 rv; - rv.mV[VX] = (getAABBMin().mV[VX] + getAABBMax().mV[VX]) * 0.5f; - rv.mV[VY] = (getAABBMin().mV[VY] + getAABBMax().mV[VY]) * 0.5f; - rv.mV[VZ] = 0.0f; - return rv; -} - -void LLParcel::extendAABB(const LLVector3& box_min, const LLVector3& box_max) -{ - // Patch up min corner of AABB - S32 i; - for (i=0; i<3; i++) - { - if (box_min.mV[i] < mAABBMin.mV[i]) - { - mAABBMin.mV[i] = box_min.mV[i]; - } - } - - // Patch up max corner of AABB - for (i=0; i<3; i++) - { - if (box_max.mV[i] > mAABBMax.mV[i]) - { - mAABBMax.mV[i] = box_max.mV[i]; - } - } -} - -bool LLParcel::addToAccessList(const LLUUID& agent_id, S32 time) -{ - if (mAccessList.size() >= (U32) PARCEL_MAX_ACCESS_LIST) - { - return false; - } - if (agent_id == getOwnerID()) - { - // Can't add owner to these lists - return false; - } - LLAccessEntry::map::iterator itor = mAccessList.begin(); - while (itor != mAccessList.end()) - { - const LLAccessEntry& entry = (*itor).second; - if (entry.mID == agent_id) - { - if (time == 0 || (entry.mTime != 0 && entry.mTime < time)) - { - mAccessList.erase(itor++); - } - else - { - // existing one expires later - return false; - } - } - else - { - ++itor; - } - } - - LLAccessEntry new_entry; - new_entry.mID = agent_id; - new_entry.mTime = time; - new_entry.mFlags = 0x0; - mAccessList[new_entry.mID] = new_entry; - return true; -} - -bool LLParcel::addToBanList(const LLUUID& agent_id, S32 time) -{ - if (mBanList.size() >= (U32) PARCEL_MAX_ACCESS_LIST) - { - // Not using ban list, so not a rational thing to do - return false; - } - if (agent_id == getOwnerID()) - { - // Can't add owner to these lists - return false; - } - - LLAccessEntry::map::iterator itor = mBanList.begin(); - while (itor != mBanList.end()) - { - const LLAccessEntry& entry = (*itor).second; - if (entry.mID == agent_id) - { - if (time == 0 || (entry.mTime != 0 && entry.mTime < time)) - { - mBanList.erase(itor++); - } - else - { - // existing one expires later - return false; - } - } - else - { - ++itor; - } - } - - LLAccessEntry new_entry; - new_entry.mID = agent_id; - new_entry.mTime = time; - new_entry.mFlags = 0x0; - mBanList[new_entry.mID] = new_entry; - return true; -} - -bool remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list, - const LLUUID& agent_id) -{ - bool removed = false; - LLAccessEntry::map::iterator itor = list->begin(); - while (itor != list->end()) - { - const LLAccessEntry& entry = (*itor).second; - if (entry.mID == agent_id) - { - list->erase(itor++); - removed = true; - } - else - { - ++itor; - } - } - return removed; -} - -bool LLParcel::removeFromAccessList(const LLUUID& agent_id) -{ - return remove_from_access_array(&mAccessList, agent_id); -} - -bool LLParcel::removeFromBanList(const LLUUID& agent_id) -{ - return remove_from_access_array(&mBanList, agent_id); -} - -// static -const std::string& LLParcel::getOwnershipStatusString(EOwnershipStatus status) -{ - return ownership_status_to_string(status); -} - -// static -const std::string& LLParcel::getCategoryString(ECategory category) -{ - return category_to_string(category); -} - -// static -const std::string& LLParcel::getCategoryUIString(ECategory category) -{ - return category_to_ui_string(category); -} - -// static -LLParcel::ECategory LLParcel::getCategoryFromString(const std::string& string) -{ - return category_string_to_category(string); -} - -// static -LLParcel::ECategory LLParcel::getCategoryFromUIString(const std::string& string) -{ - return category_ui_string_to_category(string); -} - -// static -const std::string& LLParcel::getActionString(LLParcel::EAction action) -{ - S32 index = 0; - if((action >= 0) && (action < LLParcel::A_COUNT)) - { - index = action; - } - else - { - index = A_COUNT; - } - return PARCEL_ACTION_STRING[index]; -} - -bool LLParcel::isSaleTimerExpired(const U64& time) -{ - if (!mSaleTimerExpires.getStarted()) - { - return false; - } - bool expired = mSaleTimerExpires.checkExpirationAndReset(0.0); - if (expired) - { - mSaleTimerExpires.stop(); - } - return expired; -} - -bool LLParcel::isMediaResetTimerExpired(const U64& time) -{ - if (!mMediaResetTimer.getStarted()) - { - return false; - } - bool expired = mMediaResetTimer.checkExpirationAndReset(0.0); - if (expired) - { - mMediaResetTimer.stop(); - } - return expired; -} - - -void LLParcel::startSale(const LLUUID& buyer_id, bool is_buyer_group) -{ - // TODO -- this and all Sale related methods need to move out of the LLParcel - // base class and into server-side-only LLSimParcel class - setPreviousOwnerID(mOwnerID); - setPreviouslyGroupOwned(mGroupOwned); - - mOwnerID = buyer_id; - mGroupOwned = is_buyer_group; - if(mGroupOwned) - { - mGroupID = mOwnerID; - } - else - { - mGroupID.setNull(); - } - mSaleTimerExpires.start(); - mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT)); - mStatus = OS_LEASE_PENDING; - mClaimDate = time(NULL); - setAuctionID(0); - // clear the autoreturn whenever land changes hands - setCleanOtherTime(0); -} - -void LLParcel::expireSale( - U32& type, - U8& flags, - LLUUID& from_id, - LLUUID& to_id) -{ - mSaleTimerExpires.setTimerExpirySec(0.0); - mSaleTimerExpires.stop(); - setPreviousOwnerID(LLUUID::null); - setPreviouslyGroupOwned(false); - setSellWithObjects(false); - type = TRANS_LAND_RELEASE; - mStatus = OS_NONE; - flags = pack_transaction_flags(mGroupOwned, false); - mAuthBuyerID.setNull(); - from_id = mOwnerID; - mOwnerID.setNull(); - to_id.setNull(); -} - -void LLParcel::completeSale( - U32& type, - U8& flags, - LLUUID& to_id) -{ - mSaleTimerExpires.setTimerExpirySec(0.0); - mSaleTimerExpires.stop(); - mStatus = OS_LEASED; - type = TRANS_LAND_SALE; - flags = pack_transaction_flags(mGroupOwned, mGroupOwned); - to_id = mOwnerID; - mAuthBuyerID.setNull(); - - // Purchased parcels are assumed to no longer be for sale. - // Otherwise someone can snipe the sale. - setForSale(false); - setAuctionID(0); - - // Turn off show directory, since it's a recurring fee that - // the buyer may not want. - setParcelFlag(PF_SHOW_DIRECTORY, false); - - //should be cleared on sale. - mAccessList.clear(); - mBanList.clear(); -} - -void LLParcel::clearSale() -{ - mSaleTimerExpires.setTimerExpirySec(0.0); - mSaleTimerExpires.stop(); - if(isPublic()) - { - mStatus = OS_NONE; - } - else - { - mStatus = OS_LEASED; - } - mAuthBuyerID.setNull(); - setForSale(false); - setAuctionID(0); - setPreviousOwnerID(LLUUID::null); - setPreviouslyGroupOwned(false); - setSellWithObjects(false); -} - -bool LLParcel::isPublic() const -{ - return (mOwnerID.isNull()); -} - -bool LLParcel::isBuyerAuthorized(const LLUUID& buyer_id) const -{ - if(mAuthBuyerID.isNull()) - { - return true; - } - return (mAuthBuyerID == buyer_id); -} - -void LLParcel::clearParcel() -{ - overrideParcelFlags(PF_DEFAULT); - setName(LLStringUtil::null); - setDesc(LLStringUtil::null); - setMediaURL(LLStringUtil::null); - setMediaType(LLStringUtil::null); - setMediaID(LLUUID::null); - setMediaDesc(LLStringUtil::null); - setMediaAutoScale(0); - setMediaLoop(1); - mMediaWidth = 0; - mMediaHeight = 0; - setMediaCurrentURL(LLStringUtil::null); - setMediaAllowNavigate(1); - setMediaPreventCameraZoom(0); - setMediaURLTimeout(0.0f); - setMusicURL(LLStringUtil::null); - setInEscrow(false); - setAuthorizedBuyerID(LLUUID::null); - setCategory(C_NONE); - setSnapshotID(LLUUID::null); - setUserLocation(LLVector3::zero); - setUserLookAt(LLVector3::x_axis); - setLandingType(L_LANDING_POINT); - setAuctionID(0); - setGroupID(LLUUID::null); - setPassPrice(0); - setPassHours(0.f); - mAccessList.clear(); - mBanList.clear(); - //mRenterList.reset(); -} - -void LLParcel::dump() -{ - LL_INFOS() << "parcel " << mLocalID << " area " << mArea << LL_ENDL; - LL_INFOS() << " name <" << mName << ">" << LL_ENDL; - LL_INFOS() << " desc <" << mDesc << ">" << LL_ENDL; -} - -const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status) -{ - if(status >= 0 && status < LLParcel::OS_COUNT) - { - return PARCEL_OWNERSHIP_STATUS_STRING[status]; - } - return PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT]; -} - -LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s) -{ - for(S32 i = 0; i < LLParcel::OS_COUNT; ++i) - { - if(s == PARCEL_OWNERSHIP_STATUS_STRING[i]) - { - return (LLParcel::EOwnershipStatus)i; - } - } - return LLParcel::OS_NONE; -} - -//const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action) -//{ -// S32 index = 0; -// if(action >= 0 && action < LLParcel::STEA_COUNT) -// { -// index = action; -// } -// return PARCEL_SALE_TIMER_ACTION[index]; -//} - -//LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s) -//{ -// for(S32 i = 0; i < LLParcel::STEA_COUNT; ++i) -// { -// if(0 == strcmp(s, PARCEL_SALE_TIMER_ACTION[i])) -// { -// return (LLParcel::ESaleTimerExpireAction)i; -// } -// } -// return LLParcel::STEA_REVERT; -//} - -const std::string& category_to_string(LLParcel::ECategory category) -{ - S32 index = 0; - if((category >= 0) && (category < LLParcel::C_COUNT)) - { - index = category; - } - return PARCEL_CATEGORY_STRING[index]; -} - -const std::string& category_to_ui_string(LLParcel::ECategory category) -{ - S32 index = 0; - if((category >= 0) && (category < LLParcel::C_COUNT)) - { - index = category; - } - else - { - // C_ANY = -1 , but the "Any" string is at the end of the list - index = ((S32) LLParcel::C_COUNT); - } - return PARCEL_CATEGORY_UI_STRING[index]; -} - -LLParcel::ECategory category_string_to_category(const std::string& s) -{ - for(S32 i = 0; i < LLParcel::C_COUNT; ++i) - { - if(s == PARCEL_CATEGORY_STRING[i]) - { - return (LLParcel::ECategory)i; - } - } - LL_WARNS() << "Parcel category outside of possibilities " << s << LL_ENDL; - return LLParcel::C_NONE; -} - -LLParcel::ECategory category_ui_string_to_category(const std::string& s) -{ - for(S32 i = 0; i < LLParcel::C_COUNT; ++i) - { - if(s == PARCEL_CATEGORY_UI_STRING[i]) - { - return (LLParcel::ECategory)i; - } - } - // "Any" is a valid category for searches, and - // is a distinct option from "None" and "Other" - return LLParcel::C_ANY; -} - -LLAccessEntry::map LLParcel::getExperienceKeysByType( U32 type ) const -{ - LLAccessEntry::map access; - LLAccessEntry entry; - xp_type_map_t::const_iterator it = mExperienceKeys.begin(); - for(/**/; it != mExperienceKeys.end(); ++it) - { - if(it->second == type) - { - entry.mID = it->first; - access[entry.mID] = entry; - } - } - return access; -} - -void LLParcel::clearExperienceKeysByType( U32 type ) -{ - xp_type_map_t::iterator it = mExperienceKeys.begin(); - while(it != mExperienceKeys.end()) - { - if(it->second == type) - { - mExperienceKeys.erase(it++); - } - else - { - ++it; - } - } -} - -void LLParcel::setExperienceKeyType( const LLUUID& experience_key, U32 type ) -{ - if(type == EXPERIENCE_KEY_TYPE_NONE) - { - mExperienceKeys.erase(experience_key); - } - else - { - if(countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST) - { - mExperienceKeys[experience_key] = type; - } - } -} - -U32 LLParcel::countExperienceKeyType( U32 type ) -{ - return std::count_if( - boost::begin(mExperienceKeys | boost::adaptors::map_values), - boost::end(mExperienceKeys | boost::adaptors::map_values), - [type](U32 key){ return (key == type); }); -} +/**
+ * @file llparcel.cpp
+ * @brief A land parcel.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "indra_constants.h"
+#include <iostream>
+
+#include "llparcel.h"
+#include "llstreamtools.h"
+
+#include "llmath.h"
+#include "llsd.h"
+#include "llsdutil.h"
+#include "lltransactiontypes.h"
+#include "lltransactionflags.h"
+#include "llsdutil_math.h"
+#include "message.h"
+#include "u64.h"
+#include "llregionflags.h"
+#include <boost/range/adaptor/map.hpp>
+
+static const F32 SOME_BIG_NUMBER = 1000.0f;
+static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
+static const std::string PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT+1] =
+{
+ "leased",
+ "lease_pending",
+ "abandoned",
+ "none"
+};
+
+// NOTE: Adding parcel categories also requires updating:
+// * floater_about_land.xml category combobox
+// * Web site "create event" tools
+// DO NOT DELETE ITEMS FROM THIS LIST WITHOUT DEEPLY UNDERSTANDING WHAT YOU'RE DOING.
+//
+static const std::string PARCEL_CATEGORY_STRING[LLParcel::C_COUNT] =
+{
+ "none",
+ "linden",
+ "adult",
+ "arts",
+ "store", // "business" legacy name
+ "educational",
+ "game", // "gaming" legacy name
+ "gather", // "hangout" legacy name
+ "newcomer",
+ "park",
+ "home", // "residential" legacy name
+ "shopping",
+ "stage",
+ "other",
+ "rental"
+};
+static const std::string PARCEL_CATEGORY_UI_STRING[LLParcel::C_COUNT + 1] =
+{
+ "None",
+ "Linden Location",
+ "Adult",
+ "Arts and Culture",
+ "Business",
+ "Educational",
+ "Gaming",
+ "Hangout",
+ "Newcomer Friendly",
+ "Parks and Nature",
+ "Residential",
+ "Shopping",
+ "Stage",
+ "Other",
+ "Rental",
+ "Any", // valid string for parcel searches
+};
+
+static const std::string PARCEL_ACTION_STRING[LLParcel::A_COUNT + 1] =
+{
+ "create",
+ "release",
+ "absorb",
+ "absorbed",
+ "divide",
+ "division",
+ "acquire",
+ "relinquish",
+ "confirm",
+ "unknown"
+};
+
+
+
+//const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action);
+//LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s);
+const std::string& category_to_ui_string(LLParcel::ECategory category);
+LLParcel::ECategory category_ui_string_to_category(const std::string& s);
+
+LLParcel::LLParcel()
+{
+ init(LLUUID::null, true, false, false, 0, 0, 0, 0, 0, 1.f, 0);
+}
+
+
+LLParcel::LLParcel(const LLUUID &owner_id,
+ bool modify, bool terraform, bool damage,
+ time_t claim_date, S32 claim_price_per_meter,
+ S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus,
+ bool is_group_owned)
+{
+ init( owner_id, modify, terraform, damage, claim_date,
+ claim_price_per_meter, rent_price_per_meter, area, sim_object_limit, parcel_object_bonus,
+ is_group_owned);
+}
+
+
+// virtual
+LLParcel::~LLParcel()
+{
+ // user list cleaned up by std::vector destructor.
+}
+
+void LLParcel::init(const LLUUID &owner_id,
+ bool modify, bool terraform, bool damage,
+ time_t claim_date, S32 claim_price_per_meter,
+ S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus,
+ bool is_group_owned)
+{
+ mID.setNull();
+ mOwnerID = owner_id;
+ mGroupOwned = is_group_owned;
+ mClaimDate = claim_date;
+ mClaimPricePerMeter = claim_price_per_meter;
+ mRentPricePerMeter = rent_price_per_meter;
+ mArea = area;
+ mDiscountRate = 1.0f;
+ mDrawDistance = 512.f;
+
+ mUserLookAt.setVec(0.0f, 0.f, 0.f);
+ // Default to using the parcel's landing point, if any.
+ mLandingType = L_LANDING_POINT;
+
+ // *FIX: if owner_id != null, should be owned or sale pending,
+ // investigate init callers.
+ mStatus = OS_NONE;
+ mCategory = C_NONE;
+ mAuthBuyerID.setNull();
+ //mBuyerID.setNull();
+ //mJoinNeighbors = 0x0;
+ mSaleTimerExpires.setTimerExpirySec(0);
+ mSaleTimerExpires.stop();
+ mGraceExtension = 0;
+ //mExpireAction = STEA_REVERT;
+ //mRecordTransaction = false;
+
+ mAuctionID = 0;
+ mInEscrow = false;
+
+ mParcelFlags = PF_DEFAULT;
+ setParcelFlag(PF_CREATE_OBJECTS, modify);
+ setParcelFlag(PF_ALLOW_TERRAFORM, terraform);
+ setParcelFlag(PF_ALLOW_DAMAGE, damage);
+
+ mSalePrice = 10000;
+ setName(LLStringUtil::null);
+ setDesc(LLStringUtil::null);
+ setMusicURL(LLStringUtil::null);
+ setMediaURL(LLStringUtil::null);
+ setMediaDesc(LLStringUtil::null);
+ setMediaType(LLStringUtil::null);
+ mMediaID.setNull();
+ mMediaAutoScale = 0;
+ mMediaLoop = 1;
+ mMediaWidth = 0;
+ mMediaHeight = 0;
+ setMediaCurrentURL(LLStringUtil::null);
+ mMediaAllowNavigate = 1;
+ mMediaURLTimeout = 0.0f;
+ mMediaPreventCameraZoom = 0;
+
+ mGroupID.setNull();
+
+ mPassPrice = PARCEL_PASS_PRICE_DEFAULT;
+ mPassHours = PARCEL_PASS_HOURS_DEFAULT;
+
+ mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER);
+ mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER);
+
+ mLocalID = INVALID_PARCEL_ID;
+
+ //mSimWidePrimCorrection = 0;
+ setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS)));
+ setSimWideMaxPrimCapacity(0);
+ setSimWidePrimCount(0);
+ setOwnerPrimCount(0);
+ setGroupPrimCount(0);
+ setOtherPrimCount(0);
+ setSelectedPrimCount(0);
+ setTempPrimCount(0);
+ setCleanOtherTime(0);
+ setRegionPushOverride(false);
+ setRegionDenyAnonymousOverride(false);
+ setRegionDenyAgeUnverifiedOverride(false);
+ setParcelPrimBonus(parcel_object_bonus);
+
+ setPreviousOwnerID(LLUUID::null);
+ setPreviouslyGroupOwned(false);
+
+ setSeeAVs(true);
+ setAllowGroupAVSounds(true);
+ setAllowAnyAVSounds(true);
+ setHaveNewParcelLimitData(false);
+
+ setRegionAllowEnvironmentOverride(false);
+ setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
+
+ setObscureMOAP(false);
+}
+
+void LLParcel::overrideOwner(const LLUUID& owner_id, bool is_group_owned)
+{
+ // Override with system permission (LLUUID::null)
+ // Overridden parcels have no group
+ mOwnerID = owner_id;
+ mGroupOwned = is_group_owned;
+ if(mGroupOwned)
+ {
+ mGroupID = mOwnerID;
+ }
+ else
+ {
+ mGroupID.setNull();
+ }
+ mInEscrow = false;
+}
+
+void LLParcel::overrideParcelFlags(U32 flags)
+{
+ mParcelFlags = flags;
+}
+void LLParcel::setName(const std::string& name)
+{
+ // The escaping here must match the escaping in the database
+ // abstraction layer.
+ mName = name;
+ LLStringFn::replace_nonprintable_in_ascii(mName, LL_UNKNOWN_CHAR);
+}
+
+void LLParcel::setDesc(const std::string& desc)
+{
+ // The escaping here must match the escaping in the database
+ // abstraction layer.
+ mDesc = desc;
+ mDesc = rawstr_to_utf8(mDesc);
+}
+
+void LLParcel::setMusicURL(const std::string& url)
+{
+ mMusicURL = url;
+ // The escaping here must match the escaping in the database
+ // abstraction layer.
+ // This should really filter the url in some way. Other than
+ // simply requiring non-printable.
+ LLStringFn::replace_nonprintable_in_ascii(mMusicURL, LL_UNKNOWN_CHAR);
+}
+
+void LLParcel::setMediaURL(const std::string& url)
+{
+ mMediaURL = url;
+ // The escaping here must match the escaping in the database
+ // abstraction layer if it's ever added.
+ // This should really filter the url in some way. Other than
+ // simply requiring non-printable.
+ LLStringFn::replace_nonprintable_in_ascii(mMediaURL, LL_UNKNOWN_CHAR);
+}
+
+void LLParcel::setMediaDesc(const std::string& desc)
+{
+ // The escaping here must match the escaping in the database
+ // abstraction layer.
+ mMediaDesc = desc;
+ mMediaDesc = rawstr_to_utf8(mMediaDesc);
+}
+void LLParcel::setMediaType(const std::string& type)
+{
+ // The escaping here must match the escaping in the database
+ // abstraction layer.
+ mMediaType = type;
+ mMediaType = rawstr_to_utf8(mMediaType);
+
+ // This code attempts to preserve legacy movie functioning
+ if(mMediaType.empty() && ! mMediaURL.empty())
+ {
+ setMediaType(std::string("video/vnd.secondlife.qt.legacy"));
+ }
+}
+void LLParcel::setMediaWidth(S32 width)
+{
+ mMediaWidth = width;
+}
+void LLParcel::setMediaHeight(S32 height)
+{
+ mMediaHeight = height;
+}
+
+void LLParcel::setMediaCurrentURL(const std::string& url)
+{
+ mMediaCurrentURL = url;
+ // The escaping here must match the escaping in the database
+ // abstraction layer if it's ever added.
+ // This should really filter the url in some way. Other than
+ // simply requiring non-printable.
+ LLStringFn::replace_nonprintable_in_ascii(mMediaCurrentURL, LL_UNKNOWN_CHAR);
+
+}
+
+void LLParcel::setMediaURLResetTimer(F32 time)
+{
+ mMediaResetTimer.start();
+ mMediaResetTimer.setTimerExpirySec(time);
+}
+
+// virtual
+void LLParcel::setLocalID(S32 local_id)
+{
+ mLocalID = local_id;
+}
+
+void LLParcel::setAllParcelFlags(U32 flags)
+{
+ mParcelFlags = flags;
+}
+
+void LLParcel::setParcelFlag(U32 flag, bool b)
+{
+ if (b)
+ {
+ mParcelFlags |= flag;
+ }
+ else
+ {
+ mParcelFlags &= ~flag;
+ }
+}
+
+
+bool LLParcel::allowModifyBy(const LLUUID &agent_id, const LLUUID &group_id) const
+{
+ if (agent_id == LLUUID::null)
+ {
+ // system always can enter
+ return true;
+ }
+ else if (isPublic())
+ {
+ return true;
+ }
+ else if (agent_id == mOwnerID)
+ {
+ // owner can always perform operations
+ return true;
+ }
+ else if (mParcelFlags & PF_CREATE_OBJECTS)
+ {
+ return true;
+ }
+ else if ((mParcelFlags & PF_CREATE_GROUP_OBJECTS)
+ && group_id.notNull() )
+ {
+ return (getGroupID() == group_id);
+ }
+
+ return false;
+}
+
+bool LLParcel::allowTerraformBy(const LLUUID &agent_id) const
+{
+ if (agent_id == LLUUID::null)
+ {
+ // system always can enter
+ return true;
+ }
+ else if(OS_LEASED == mStatus)
+ {
+ if(agent_id == mOwnerID)
+ {
+ // owner can modify leased land
+ return true;
+ }
+ else
+ {
+ // otherwise check other people
+ return mParcelFlags & PF_ALLOW_TERRAFORM;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+
+void LLParcel::setArea(S32 area, S32 sim_object_limit)
+{
+ mArea = area;
+ setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS)));
+}
+
+void LLParcel::setDiscountRate(F32 rate)
+{
+ // this is to make sure that the rate is at least sane - this is
+ // not intended to enforce economy rules. It only enfoces that the
+ // rate is a scaler between 0 and 1.
+ mDiscountRate = llclampf(rate);
+}
+
+
+//-----------------------------------------------------------
+// File input and output
+//-----------------------------------------------------------
+
+bool LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entry)
+{
+ skip_to_end_of_next_keyword("{", input_stream);
+ while (input_stream.good())
+ {
+ skip_comments_and_emptyspace(input_stream);
+ std::string line, keyword, value;
+ get_line(line, input_stream, MAX_STRING);
+ get_keyword_and_value(keyword, value, line);
+
+ if ("}" == keyword)
+ {
+ break;
+ }
+ else if ("id" == keyword)
+ {
+ entry->mID.set( value );
+ }
+ else if ("name" == keyword)
+ {
+ // deprecated
+ }
+ else if ("time" == keyword)
+ {
+ S32 when{};
+ LLStringUtil::convertToS32(value, when);
+ entry->mTime = when;
+ }
+ else if ("flags" == keyword)
+ {
+ U32 setting{};
+ LLStringUtil::convertToU32(value, setting);
+ entry->mFlags = setting;
+ }
+ else
+ {
+ LL_WARNS() << "Unknown keyword in parcel access entry section: <"
+ << keyword << ">" << LL_ENDL;
+ }
+ }
+ return input_stream.good();
+}
+
+// Assumes we are in a block "ParcelData"
+void LLParcel::packMessage(LLMessageSystem* msg)
+{
+ msg->addU32Fast( _PREHASH_ParcelFlags, getParcelFlags() );
+ msg->addS32Fast( _PREHASH_SalePrice, getSalePrice() );
+ msg->addStringFast( _PREHASH_Name, getName() );
+ msg->addStringFast( _PREHASH_Desc, getDesc() );
+ msg->addStringFast( _PREHASH_MusicURL, getMusicURL() );
+ msg->addStringFast( _PREHASH_MediaURL, getMediaURL() );
+ msg->addU8 ( "MediaAutoScale", getMediaAutoScale () );
+ msg->addUUIDFast( _PREHASH_MediaID, getMediaID() );
+ msg->addUUIDFast( _PREHASH_GroupID, getGroupID() );
+ msg->addS32Fast( _PREHASH_PassPrice, mPassPrice );
+ msg->addF32Fast( _PREHASH_PassHours, mPassHours );
+ msg->addU8Fast( _PREHASH_Category, (U8)mCategory);
+ msg->addUUIDFast( _PREHASH_AuthBuyerID, mAuthBuyerID);
+ msg->addUUIDFast( _PREHASH_SnapshotID, mSnapshotID);
+ msg->addVector3Fast(_PREHASH_UserLocation, mUserLocation);
+ msg->addVector3Fast(_PREHASH_UserLookAt, mUserLookAt);
+ msg->addU8Fast( _PREHASH_LandingType, (U8)mLandingType);
+}
+
+// Assumes we are in a block "ParcelData"
+void LLParcel::packMessage(LLSD& msg)
+{
+ // used in the viewer, the sim uses it's own packer
+ msg["local_id"] = getLocalID();
+ msg["parcel_flags"] = ll_sd_from_U32(getParcelFlags());
+ msg["sale_price"] = getSalePrice();
+ msg["name"] = getName();
+ msg["description"] = getDesc();
+ msg["music_url"] = getMusicURL();
+ msg["media_url"] = getMediaURL();
+ msg["media_desc"] = getMediaDesc();
+ msg["media_type"] = getMediaType();
+ msg["media_width"] = getMediaWidth();
+ msg["media_height"] = getMediaHeight();
+ msg["auto_scale"] = getMediaAutoScale();
+ msg["media_loop"] = getMediaLoop();
+ msg["media_current_url"] = getMediaCurrentURL();
+ msg["obscure_media"] = false; // OBSOLETE - no longer used
+ msg["obscure_music"] = false; // OBSOLETE - no longer used
+ msg["media_id"] = getMediaID();
+ msg["media_allow_navigate"] = getMediaAllowNavigate();
+ msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom();
+ msg["media_url_timeout"] = getMediaURLTimeout();
+ msg["group_id"] = getGroupID();
+ msg["pass_price"] = mPassPrice;
+ msg["pass_hours"] = mPassHours;
+ msg["category"] = (U8)mCategory;
+ msg["auth_buyer_id"] = mAuthBuyerID;
+ msg["snapshot_id"] = mSnapshotID;
+ msg["user_location"] = ll_sd_from_vector3(mUserLocation);
+ msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt);
+ msg["landing_type"] = (U8)mLandingType;
+ msg["see_avs"] = (LLSD::Boolean) getSeeAVs();
+ msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds();
+ msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds();
+ msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP();
+}
+
+
+void LLParcel::unpackMessage(LLMessageSystem* msg)
+{
+ std::string buffer;
+
+ msg->getU32Fast( _PREHASH_ParcelData,_PREHASH_ParcelFlags, mParcelFlags );
+ msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_SalePrice, mSalePrice );
+ msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Name, buffer );
+ setName(buffer);
+ msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Desc, buffer );
+ setDesc(buffer);
+ msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MusicURL, buffer );
+ setMusicURL(buffer);
+ msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MediaURL, buffer );
+ setMediaURL(buffer);
+
+ bool see_avs = true; // All default to true for legacy server behavior
+ bool any_av_sounds = true;
+ bool group_av_sounds = true;
+ bool have_new_parcel_limit_data = (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_SeeAVs) > 0); // New version of server should send all 3 of these values
+ have_new_parcel_limit_data &= (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_AnyAVSounds) > 0);
+ have_new_parcel_limit_data &= (msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_GroupAVSounds) > 0);
+ if (have_new_parcel_limit_data)
+ {
+ msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_SeeAVs, see_avs);
+ msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_AnyAVSounds, any_av_sounds);
+ msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_GroupAVSounds, group_av_sounds);
+ }
+ setSeeAVs((bool) see_avs);
+ setAllowAnyAVSounds((bool) any_av_sounds);
+ setAllowGroupAVSounds((bool) group_av_sounds);
+
+ setHaveNewParcelLimitData(have_new_parcel_limit_data);
+
+ // non-optimized version
+ msg->getU8 ( "ParcelData", "MediaAutoScale", mMediaAutoScale );
+
+ msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_MediaID, mMediaID );
+ msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_GroupID, mGroupID );
+ msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_PassPrice, mPassPrice );
+ msg->getF32Fast( _PREHASH_ParcelData,_PREHASH_PassHours, mPassHours );
+ U8 category;
+ msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_Category, category);
+ mCategory = (ECategory)category;
+ msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_AuthBuyerID, mAuthBuyerID);
+ msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_SnapshotID, mSnapshotID);
+ msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLocation, mUserLocation);
+ msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLookAt, mUserLookAt);
+ U8 landing_type;
+ msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_LandingType, landing_type);
+ mLandingType = (ELandingType)landing_type;
+
+ // New Media Data
+ // Note: the message has been converted to TCP
+ if(msg->has("MediaData"))
+ {
+ msg->getString("MediaData", "MediaDesc", buffer);
+ setMediaDesc(buffer);
+ msg->getString("MediaData", "MediaType", buffer);
+ setMediaType(buffer);
+ msg->getS32("MediaData", "MediaWidth", mMediaWidth);
+ msg->getS32("MediaData", "MediaHeight", mMediaHeight);
+ msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop );
+ // the ObscureMedia and ObscureMusic flags previously set here are no longer used
+ }
+ else
+ {
+ setMediaType(std::string("video/vnd.secondlife.qt.legacy"));
+ setMediaDesc(std::string("No Description available without Server Upgrade"));
+ mMediaLoop = true;
+ }
+
+ if(msg->getNumberOfBlocks("MediaLinkSharing") > 0)
+ {
+ msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer);
+ setMediaCurrentURL(buffer);
+ msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate );
+ msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom );
+ msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout);
+ }
+ else
+ {
+ setMediaCurrentURL(LLStringUtil::null);
+ }
+
+}
+
+void LLParcel::packAccessEntries(LLMessageSystem* msg,
+ const std::map<LLUUID,LLAccessEntry>& list)
+{
+ LLAccessEntry::map::const_iterator cit = list.begin();
+ LLAccessEntry::map::const_iterator end = list.end();
+
+ if (cit == end)
+ {
+ msg->nextBlockFast(_PREHASH_List);
+ msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
+ msg->addS32Fast(_PREHASH_Time, 0 );
+ msg->addU32Fast(_PREHASH_Flags, 0 );
+ return;
+ }
+
+ for ( ; cit != end; ++cit)
+ {
+ const LLAccessEntry& entry = (*cit).second;
+
+ msg->nextBlockFast(_PREHASH_List);
+ msg->addUUIDFast(_PREHASH_ID, entry.mID );
+ msg->addS32Fast(_PREHASH_Time, entry.mTime );
+ msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
+ }
+}
+
+
+void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
+ std::map<LLUUID,LLAccessEntry>* list)
+{
+ LLUUID id;
+ S32 time;
+ U32 flags;
+
+ S32 i;
+ S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
+ for (i = 0; i < count; i++)
+ {
+ msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
+ msg->getS32Fast( _PREHASH_List, _PREHASH_Time, time, i);
+ msg->getU32Fast( _PREHASH_List, _PREHASH_Flags, flags, i);
+
+ if (id.notNull())
+ {
+ LLAccessEntry entry;
+ entry.mID = id;
+ entry.mTime = time;
+ entry.mFlags = flags;
+
+ (*list)[entry.mID] = entry;
+ }
+ }
+}
+
+
+void LLParcel::unpackExperienceEntries( LLMessageSystem* msg, U32 type )
+{
+ LLUUID id;
+
+ S32 i;
+ S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
+ for (i = 0; i < count; i++)
+ {
+ msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
+
+ if (id.notNull())
+ {
+ mExperienceKeys[id]=type;
+ }
+ }
+}
+
+
+
+void LLParcel::expirePasses(S32 now)
+{
+ LLAccessEntry::map::iterator itor = mAccessList.begin();
+ while (itor != mAccessList.end())
+ {
+ const LLAccessEntry& entry = (*itor).second;
+
+ if (entry.mTime != 0 && entry.mTime < now)
+ {
+ mAccessList.erase(itor++);
+ }
+ else
+ {
+ ++itor;
+ }
+ }
+}
+
+
+bool LLParcel::operator==(const LLParcel &rhs) const
+{
+ if (mOwnerID != rhs.mOwnerID)
+ return false;
+
+ if (mParcelFlags != rhs.mParcelFlags)
+ return false;
+
+ if (mClaimDate != rhs.mClaimDate)
+ return false;
+
+ if (mClaimPricePerMeter != rhs.mClaimPricePerMeter)
+ return false;
+
+ if (mRentPricePerMeter != rhs.mRentPricePerMeter)
+ return false;
+
+ return true;
+}
+
+// Calculate rent
+S32 LLParcel::getTotalRent() const
+{
+ return (S32)floor(0.5f + (F32)mArea * (F32)mRentPricePerMeter * (1.0f - mDiscountRate));
+}
+
+F32 LLParcel::getAdjustedRentPerMeter() const
+{
+ return ((F32)mRentPricePerMeter * (1.0f - mDiscountRate));
+}
+
+LLVector3 LLParcel::getCenterpoint() const
+{
+ LLVector3 rv;
+ rv.mV[VX] = (getAABBMin().mV[VX] + getAABBMax().mV[VX]) * 0.5f;
+ rv.mV[VY] = (getAABBMin().mV[VY] + getAABBMax().mV[VY]) * 0.5f;
+ rv.mV[VZ] = 0.0f;
+ return rv;
+}
+
+void LLParcel::extendAABB(const LLVector3& box_min, const LLVector3& box_max)
+{
+ // Patch up min corner of AABB
+ S32 i;
+ for (i=0; i<3; i++)
+ {
+ if (box_min.mV[i] < mAABBMin.mV[i])
+ {
+ mAABBMin.mV[i] = box_min.mV[i];
+ }
+ }
+
+ // Patch up max corner of AABB
+ for (i=0; i<3; i++)
+ {
+ if (box_max.mV[i] > mAABBMax.mV[i])
+ {
+ mAABBMax.mV[i] = box_max.mV[i];
+ }
+ }
+}
+
+bool LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
+{
+ if (mAccessList.size() >= (U32) PARCEL_MAX_ACCESS_LIST)
+ {
+ return false;
+ }
+ if (agent_id == getOwnerID())
+ {
+ // Can't add owner to these lists
+ return false;
+ }
+ LLAccessEntry::map::iterator itor = mAccessList.begin();
+ while (itor != mAccessList.end())
+ {
+ const LLAccessEntry& entry = (*itor).second;
+ if (entry.mID == agent_id)
+ {
+ if (time == 0 || (entry.mTime != 0 && entry.mTime < time))
+ {
+ mAccessList.erase(itor++);
+ }
+ else
+ {
+ // existing one expires later
+ return false;
+ }
+ }
+ else
+ {
+ ++itor;
+ }
+ }
+
+ LLAccessEntry new_entry;
+ new_entry.mID = agent_id;
+ new_entry.mTime = time;
+ new_entry.mFlags = 0x0;
+ mAccessList[new_entry.mID] = new_entry;
+ return true;
+}
+
+bool LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
+{
+ if (mBanList.size() >= (U32) PARCEL_MAX_ACCESS_LIST)
+ {
+ // Not using ban list, so not a rational thing to do
+ return false;
+ }
+ if (agent_id == getOwnerID())
+ {
+ // Can't add owner to these lists
+ return false;
+ }
+
+ LLAccessEntry::map::iterator itor = mBanList.begin();
+ while (itor != mBanList.end())
+ {
+ const LLAccessEntry& entry = (*itor).second;
+ if (entry.mID == agent_id)
+ {
+ if (time == 0 || (entry.mTime != 0 && entry.mTime < time))
+ {
+ mBanList.erase(itor++);
+ }
+ else
+ {
+ // existing one expires later
+ return false;
+ }
+ }
+ else
+ {
+ ++itor;
+ }
+ }
+
+ LLAccessEntry new_entry;
+ new_entry.mID = agent_id;
+ new_entry.mTime = time;
+ new_entry.mFlags = 0x0;
+ mBanList[new_entry.mID] = new_entry;
+ return true;
+}
+
+bool remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
+ const LLUUID& agent_id)
+{
+ bool removed = false;
+ LLAccessEntry::map::iterator itor = list->begin();
+ while (itor != list->end())
+ {
+ const LLAccessEntry& entry = (*itor).second;
+ if (entry.mID == agent_id)
+ {
+ list->erase(itor++);
+ removed = true;
+ }
+ else
+ {
+ ++itor;
+ }
+ }
+ return removed;
+}
+
+bool LLParcel::removeFromAccessList(const LLUUID& agent_id)
+{
+ return remove_from_access_array(&mAccessList, agent_id);
+}
+
+bool LLParcel::removeFromBanList(const LLUUID& agent_id)
+{
+ return remove_from_access_array(&mBanList, agent_id);
+}
+
+// static
+const std::string& LLParcel::getOwnershipStatusString(EOwnershipStatus status)
+{
+ return ownership_status_to_string(status);
+}
+
+// static
+const std::string& LLParcel::getCategoryString(ECategory category)
+{
+ return category_to_string(category);
+}
+
+// static
+const std::string& LLParcel::getCategoryUIString(ECategory category)
+{
+ return category_to_ui_string(category);
+}
+
+// static
+LLParcel::ECategory LLParcel::getCategoryFromString(const std::string& string)
+{
+ return category_string_to_category(string);
+}
+
+// static
+LLParcel::ECategory LLParcel::getCategoryFromUIString(const std::string& string)
+{
+ return category_ui_string_to_category(string);
+}
+
+// static
+const std::string& LLParcel::getActionString(LLParcel::EAction action)
+{
+ S32 index = 0;
+ if((action >= 0) && (action < LLParcel::A_COUNT))
+ {
+ index = action;
+ }
+ else
+ {
+ index = A_COUNT;
+ }
+ return PARCEL_ACTION_STRING[index];
+}
+
+bool LLParcel::isSaleTimerExpired(const U64& time)
+{
+ if (!mSaleTimerExpires.getStarted())
+ {
+ return false;
+ }
+ bool expired = mSaleTimerExpires.checkExpirationAndReset(0.0);
+ if (expired)
+ {
+ mSaleTimerExpires.stop();
+ }
+ return expired;
+}
+
+bool LLParcel::isMediaResetTimerExpired(const U64& time)
+{
+ if (!mMediaResetTimer.getStarted())
+ {
+ return false;
+ }
+ bool expired = mMediaResetTimer.checkExpirationAndReset(0.0);
+ if (expired)
+ {
+ mMediaResetTimer.stop();
+ }
+ return expired;
+}
+
+
+void LLParcel::startSale(const LLUUID& buyer_id, bool is_buyer_group)
+{
+ // TODO -- this and all Sale related methods need to move out of the LLParcel
+ // base class and into server-side-only LLSimParcel class
+ setPreviousOwnerID(mOwnerID);
+ setPreviouslyGroupOwned(mGroupOwned);
+
+ mOwnerID = buyer_id;
+ mGroupOwned = is_buyer_group;
+ if(mGroupOwned)
+ {
+ mGroupID = mOwnerID;
+ }
+ else
+ {
+ mGroupID.setNull();
+ }
+ mSaleTimerExpires.start();
+ mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT));
+ mStatus = OS_LEASE_PENDING;
+ mClaimDate = time(NULL);
+ setAuctionID(0);
+ // clear the autoreturn whenever land changes hands
+ setCleanOtherTime(0);
+}
+
+void LLParcel::expireSale(
+ U32& type,
+ U8& flags,
+ LLUUID& from_id,
+ LLUUID& to_id)
+{
+ mSaleTimerExpires.setTimerExpirySec(0.0);
+ mSaleTimerExpires.stop();
+ setPreviousOwnerID(LLUUID::null);
+ setPreviouslyGroupOwned(false);
+ setSellWithObjects(false);
+ type = TRANS_LAND_RELEASE;
+ mStatus = OS_NONE;
+ flags = pack_transaction_flags(mGroupOwned, false);
+ mAuthBuyerID.setNull();
+ from_id = mOwnerID;
+ mOwnerID.setNull();
+ to_id.setNull();
+}
+
+void LLParcel::completeSale(
+ U32& type,
+ U8& flags,
+ LLUUID& to_id)
+{
+ mSaleTimerExpires.setTimerExpirySec(0.0);
+ mSaleTimerExpires.stop();
+ mStatus = OS_LEASED;
+ type = TRANS_LAND_SALE;
+ flags = pack_transaction_flags(mGroupOwned, mGroupOwned);
+ to_id = mOwnerID;
+ mAuthBuyerID.setNull();
+
+ // Purchased parcels are assumed to no longer be for sale.
+ // Otherwise someone can snipe the sale.
+ setForSale(false);
+ setAuctionID(0);
+
+ // Turn off show directory, since it's a recurring fee that
+ // the buyer may not want.
+ setParcelFlag(PF_SHOW_DIRECTORY, false);
+
+ //should be cleared on sale.
+ mAccessList.clear();
+ mBanList.clear();
+}
+
+void LLParcel::clearSale()
+{
+ mSaleTimerExpires.setTimerExpirySec(0.0);
+ mSaleTimerExpires.stop();
+ if(isPublic())
+ {
+ mStatus = OS_NONE;
+ }
+ else
+ {
+ mStatus = OS_LEASED;
+ }
+ mAuthBuyerID.setNull();
+ setForSale(false);
+ setAuctionID(0);
+ setPreviousOwnerID(LLUUID::null);
+ setPreviouslyGroupOwned(false);
+ setSellWithObjects(false);
+}
+
+bool LLParcel::isPublic() const
+{
+ return (mOwnerID.isNull());
+}
+
+bool LLParcel::isBuyerAuthorized(const LLUUID& buyer_id) const
+{
+ if(mAuthBuyerID.isNull())
+ {
+ return true;
+ }
+ return (mAuthBuyerID == buyer_id);
+}
+
+void LLParcel::clearParcel()
+{
+ overrideParcelFlags(PF_DEFAULT);
+ setName(LLStringUtil::null);
+ setDesc(LLStringUtil::null);
+ setMediaURL(LLStringUtil::null);
+ setMediaType(LLStringUtil::null);
+ setMediaID(LLUUID::null);
+ setMediaDesc(LLStringUtil::null);
+ setMediaAutoScale(0);
+ setMediaLoop(1);
+ mMediaWidth = 0;
+ mMediaHeight = 0;
+ setMediaCurrentURL(LLStringUtil::null);
+ setMediaAllowNavigate(1);
+ setMediaPreventCameraZoom(0);
+ setMediaURLTimeout(0.0f);
+ setMusicURL(LLStringUtil::null);
+ setInEscrow(false);
+ setAuthorizedBuyerID(LLUUID::null);
+ setCategory(C_NONE);
+ setSnapshotID(LLUUID::null);
+ setUserLocation(LLVector3::zero);
+ setUserLookAt(LLVector3::x_axis);
+ setLandingType(L_LANDING_POINT);
+ setAuctionID(0);
+ setGroupID(LLUUID::null);
+ setPassPrice(0);
+ setPassHours(0.f);
+ mAccessList.clear();
+ mBanList.clear();
+ //mRenterList.reset();
+}
+
+void LLParcel::dump()
+{
+ LL_INFOS() << "parcel " << mLocalID << " area " << mArea << LL_ENDL;
+ LL_INFOS() << " name <" << mName << ">" << LL_ENDL;
+ LL_INFOS() << " desc <" << mDesc << ">" << LL_ENDL;
+}
+
+const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status)
+{
+ if(status >= 0 && status < LLParcel::OS_COUNT)
+ {
+ return PARCEL_OWNERSHIP_STATUS_STRING[status];
+ }
+ return PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT];
+}
+
+LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s)
+{
+ for(S32 i = 0; i < LLParcel::OS_COUNT; ++i)
+ {
+ if(s == PARCEL_OWNERSHIP_STATUS_STRING[i])
+ {
+ return (LLParcel::EOwnershipStatus)i;
+ }
+ }
+ return LLParcel::OS_NONE;
+}
+
+//const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action)
+//{
+// S32 index = 0;
+// if(action >= 0 && action < LLParcel::STEA_COUNT)
+// {
+// index = action;
+// }
+// return PARCEL_SALE_TIMER_ACTION[index];
+//}
+
+//LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s)
+//{
+// for(S32 i = 0; i < LLParcel::STEA_COUNT; ++i)
+// {
+// if(0 == strcmp(s, PARCEL_SALE_TIMER_ACTION[i]))
+// {
+// return (LLParcel::ESaleTimerExpireAction)i;
+// }
+// }
+// return LLParcel::STEA_REVERT;
+//}
+
+const std::string& category_to_string(LLParcel::ECategory category)
+{
+ S32 index = 0;
+ if((category >= 0) && (category < LLParcel::C_COUNT))
+ {
+ index = category;
+ }
+ return PARCEL_CATEGORY_STRING[index];
+}
+
+const std::string& category_to_ui_string(LLParcel::ECategory category)
+{
+ S32 index = 0;
+ if((category >= 0) && (category < LLParcel::C_COUNT))
+ {
+ index = category;
+ }
+ else
+ {
+ // C_ANY = -1 , but the "Any" string is at the end of the list
+ index = ((S32) LLParcel::C_COUNT);
+ }
+ return PARCEL_CATEGORY_UI_STRING[index];
+}
+
+LLParcel::ECategory category_string_to_category(const std::string& s)
+{
+ for(S32 i = 0; i < LLParcel::C_COUNT; ++i)
+ {
+ if(s == PARCEL_CATEGORY_STRING[i])
+ {
+ return (LLParcel::ECategory)i;
+ }
+ }
+ LL_WARNS() << "Parcel category outside of possibilities " << s << LL_ENDL;
+ return LLParcel::C_NONE;
+}
+
+LLParcel::ECategory category_ui_string_to_category(const std::string& s)
+{
+ for(S32 i = 0; i < LLParcel::C_COUNT; ++i)
+ {
+ if(s == PARCEL_CATEGORY_UI_STRING[i])
+ {
+ return (LLParcel::ECategory)i;
+ }
+ }
+ // "Any" is a valid category for searches, and
+ // is a distinct option from "None" and "Other"
+ return LLParcel::C_ANY;
+}
+
+LLAccessEntry::map LLParcel::getExperienceKeysByType( U32 type ) const
+{
+ LLAccessEntry::map access;
+ LLAccessEntry entry;
+ xp_type_map_t::const_iterator it = mExperienceKeys.begin();
+ for(/**/; it != mExperienceKeys.end(); ++it)
+ {
+ if(it->second == type)
+ {
+ entry.mID = it->first;
+ access[entry.mID] = entry;
+ }
+ }
+ return access;
+}
+
+void LLParcel::clearExperienceKeysByType( U32 type )
+{
+ xp_type_map_t::iterator it = mExperienceKeys.begin();
+ while(it != mExperienceKeys.end())
+ {
+ if(it->second == type)
+ {
+ mExperienceKeys.erase(it++);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
+void LLParcel::setExperienceKeyType( const LLUUID& experience_key, U32 type )
+{
+ if(type == EXPERIENCE_KEY_TYPE_NONE)
+ {
+ mExperienceKeys.erase(experience_key);
+ }
+ else
+ {
+ if(countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST)
+ {
+ mExperienceKeys[experience_key] = type;
+ }
+ }
+}
+
+U32 LLParcel::countExperienceKeyType( U32 type )
+{
+ return std::count_if(
+ boost::begin(mExperienceKeys | boost::adaptors::map_values),
+ boost::end(mExperienceKeys | boost::adaptors::map_values),
+ [type](U32 key){ return (key == type); });
+}
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 70522d3682..06232f3d47 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -1,677 +1,677 @@ -/** - * @file llparcel.h - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLPARCEL_H -#define LL_LLPARCEL_H - -#include <time.h> -#include <iostream> - -#include "lluuid.h" -#include "llparcelflags.h" -#include "llpermissions.h" -#include "lltimer.h" -#include "v3math.h" -#include "llsettingsdaycycle.h" - -// Grid out of which parcels taken is stepped every 4 meters. -const F32 PARCEL_GRID_STEP_METERS = 4.f; - -// Area of one "square" of parcel -const S32 PARCEL_UNIT_AREA = 16; - -// Height _above_ground_ that parcel boundary ends -const F32 PARCEL_HEIGHT = 50.f; - -//Height above ground which parcel boundries exist for explicitly banned avatars -const F32 BAN_HEIGHT = 5000.f; - -// Maximum number of entries in an access list -const S32 PARCEL_MAX_ACCESS_LIST = 300; -//Maximum number of entires in an update packet -//for access/ban lists. -const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f; - -// Maximum number of experiences -const S32 PARCEL_MAX_EXPERIENCE_LIST = 24; - -// Weekly charge for listing a parcel in the directory -const S32 PARCEL_DIRECTORY_FEE = 30; - -const S32 PARCEL_PASS_PRICE_DEFAULT = 10; -const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f; - -// Number of "chunks" in which parcel overlay data is sent -// Chunk 0 = southern rows, entire width -const S32 PARCEL_OVERLAY_CHUNKS = 4; - -// Bottom three bits are a color index for the land overlay -const U8 PARCEL_COLOR_MASK = 0x07; -const U8 PARCEL_PUBLIC = 0x00; -const U8 PARCEL_OWNED = 0x01; -const U8 PARCEL_GROUP = 0x02; -const U8 PARCEL_SELF = 0x03; -const U8 PARCEL_FOR_SALE = 0x04; -const U8 PARCEL_AUCTION = 0x05; -// unused 0x06 -// unused 0x07 -// flag, unused 0x08 -const U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility -const U8 PARCEL_SOUND_LOCAL = 0x20; -const U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge -const U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge - -// Transmission results for parcel properties -const S32 PARCEL_RESULT_NO_DATA = -1; -const S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel -const S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels - -const S32 SELECTED_PARCEL_SEQ_ID = -10000; -const S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000; -const S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000; -const S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000; -const S32 HOVERED_PARCEL_SEQ_ID = -50000; - -const U32 RT_NONE = 0x1 << 0; -const U32 RT_OWNER = 0x1 << 1; -const U32 RT_GROUP = 0x1 << 2; -const U32 RT_OTHER = 0x1 << 3; -const U32 RT_LIST = 0x1 << 4; -const U32 RT_SELL = 0x1 << 5; - -const S32 INVALID_PARCEL_ID = -1; - -const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2; -// if Region settings are used, parcel env. version is -1 -const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1; - -// Timeouts for parcels -// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 -const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); - -// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 -const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); -// ***** TESTING is 10 minutes -//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); - -// default sale timeout is 2 days -> 172800000000 -const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); - -// more grace period extensions. -const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); - -// if more than 100,000s before sale revert, and no extra extension -// has been given, go ahead and extend it more. That's about 1.2 days. -const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; - - - -class LLMessageSystem; -class LLSD; - -class LLAccessEntry -{ -public: - - typedef std::map<LLUUID,LLAccessEntry> map; - - LLAccessEntry() - : mTime(0), - mFlags(0) - {} - - LLUUID mID; // Agent ID - S32 mTime; // Time (unix seconds) when entry expires - U32 mFlags; // Not used - currently should always be zero -}; - - -class LLParcel -{ -public: - enum EOwnershipStatus - { - OS_LEASED = 0, - OS_LEASE_PENDING = 1, - OS_ABANDONED = 2, - OS_COUNT = 3, - OS_NONE = -1 - }; - enum ECategory - { - C_NONE = 0, - C_LINDEN, - C_ADULT, - C_ARTS, // "arts & culture" - C_BUSINESS, // was "store" - C_EDUCATIONAL, - C_GAMING, // was "game" - C_HANGOUT, // was "gathering place" - C_NEWCOMER, - C_PARK, // "parks & nature" - C_RESIDENTIAL, // was "homestead" - C_SHOPPING, - C_STAGE, - C_OTHER, - C_RENTAL, - C_COUNT, - C_ANY = -1 // only useful in queries - }; - enum EAction - { - A_CREATE = 0, - A_RELEASE = 1, - A_ABSORB = 2, - A_ABSORBED = 3, - A_DIVIDE = 4, - A_DIVISION = 5, - A_ACQUIRE = 6, - A_RELINQUISH = 7, - A_CONFIRM = 8, - A_COUNT = 9, - A_UNKNOWN = -1 - }; - - enum ELandingType - { - L_NONE = 0, - L_LANDING_POINT = 1, - L_DIRECT = 2 - }; - - // CREATORS - LLParcel(); - LLParcel( - const LLUUID &owner_id, - bool modify, - bool terraform, - bool damage, - time_t claim_date, - S32 claim_price, - S32 rent_price, - S32 area, - S32 sim_object_limit, - F32 parcel_object_bonus, - bool is_group_owned = false); - virtual ~LLParcel(); - - void init( - const LLUUID &owner_id, - bool modify, - bool terraform, - bool damage, - time_t claim_date, - S32 claim_price, - S32 rent_price, - S32 area, - S32 sim_object_limit, - F32 parcel_object_bonus, - bool is_group_owned = false); - - // TODO: make an actual copy constructor for this - void overrideParcelFlags(U32 flags); - // if you specify an agent id here, the group id will be zeroed - void overrideOwner( - const LLUUID& owner_id, - bool is_group_owned = false); - void overrideSaleTimerExpires(F32 secs_left) { mSaleTimerExpires.setTimerExpirySec(secs_left); } - - // MANIPULATORS - void generateNewID() { mID.generate(); } - void setName(const std::string& name); - void setDesc(const std::string& desc); - void setMusicURL(const std::string& url); - void setMediaURL(const std::string& url); - void setMediaType(const std::string& type); - void setMediaDesc(const std::string& desc); - void setMediaID(const LLUUID& id) { mMediaID = id; } - void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } - void setMediaLoop (U8 loop) { mMediaLoop = loop; } - void setMediaWidth(S32 width); - void setMediaHeight(S32 height); - void setMediaCurrentURL(const std::string& url); - void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; } - void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; } - void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; } - - void setMediaURLResetTimer(F32 time); - virtual void setLocalID(S32 local_id); - - // blow away all the extra stuff lurking in parcels, including urls, access lists, etc - void clearParcel(); - - // This value is not persisted out to the parcel file, it is only - // a per-process blocker for attempts to purchase. - void setInEscrow(bool in_escrow) { mInEscrow = in_escrow; } - - void setAuthorizedBuyerID(const LLUUID& id) { mAuthBuyerID = id; } - //void overrideBuyerID(const LLUUID& id) { mBuyerID = id; } - void setCategory(ECategory category) { mCategory = category; } - void setSnapshotID(const LLUUID& id) { mSnapshotID = id; } - void setUserLocation(const LLVector3& pos) { mUserLocation = pos; } - void setUserLookAt(const LLVector3& rot) { mUserLookAt = rot; } - void setLandingType(const ELandingType type) { mLandingType = type; } - void setSeeAVs(bool see_avs) { mSeeAVs = see_avs; } - void setHaveNewParcelLimitData(bool have_new_parcel_data) { mHaveNewParcelLimitData = have_new_parcel_data; } // Remove this once hidden AV feature is fully available grid-wide - - void setAuctionID(U32 auction_id) { mAuctionID = auction_id;} - - void setAllParcelFlags(U32 flags); - void setParcelFlag(U32 flag, bool b); - - virtual void setArea(S32 area, S32 sim_object_limit); - void setDiscountRate(F32 rate); - - void setAllowModify(bool b) { setParcelFlag(PF_CREATE_OBJECTS, b); } - void setAllowGroupModify(bool b) { setParcelFlag(PF_CREATE_GROUP_OBJECTS, b); } - void setAllowAllObjectEntry(bool b) { setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, b); } - void setAllowGroupObjectEntry(bool b) { setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, b); } - void setAllowTerraform(bool b){setParcelFlag(PF_ALLOW_TERRAFORM, b); } - void setAllowDamage(bool b) { setParcelFlag(PF_ALLOW_DAMAGE, b); } - void setAllowFly(bool b) { setParcelFlag(PF_ALLOW_FLY, b); } - void setAllowGroupScripts(bool b) { setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); } - void setAllowOtherScripts(bool b) { setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); } - void setAllowDeedToGroup(bool b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); } - void setContributeWithDeed(bool b) { setParcelFlag(PF_CONTRIBUTE_WITH_DEED, b); } - void setForSale(bool b) { setParcelFlag(PF_FOR_SALE, b); } - void setSoundOnly(bool b) { setParcelFlag(PF_SOUND_LOCAL, b); } - void setDenyAnonymous(bool b) { setParcelFlag(PF_DENY_ANONYMOUS, b); } - void setDenyAgeUnverified(bool b) { setParcelFlag(PF_DENY_AGEUNVERIFIED, b); } - void setRestrictPushObject(bool b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); } - void setAllowGroupAVSounds(bool b) { mAllowGroupAVSounds = b; } - void setAllowAnyAVSounds(bool b) { mAllowAnyAVSounds = b; } - void setObscureMOAP(bool b) { mObscureMOAP = b; } - - void setDrawDistance(F32 dist) { mDrawDistance = dist; } - void setSalePrice(S32 price) { mSalePrice = price; } - void setGroupID(const LLUUID& id) { mGroupID = id; } - //void setGroupName(const std::string& s) { mGroupName.assign(s); } - void setPassPrice(S32 price) { mPassPrice = price; } - void setPassHours(F32 hours) { mPassHours = hours; } - -// bool importStream(std::istream& input_stream); - bool importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); - // bool exportStream(std::ostream& output_stream); - - void packMessage(LLMessageSystem* msg); - void packMessage(LLSD& msg); - void unpackMessage(LLMessageSystem* msg); - - void packAccessEntries(LLMessageSystem* msg, - const std::map<LLUUID,LLAccessEntry>& list); - void unpackAccessEntries(LLMessageSystem* msg, - std::map<LLUUID,LLAccessEntry>* list); - - void unpackExperienceEntries(LLMessageSystem* msg, U32 type); - - - void setAABBMin(const LLVector3& min) { mAABBMin = min; } - void setAABBMax(const LLVector3& max) { mAABBMax = max; } - - // Extend AABB to include rectangle from min to max. - void extendAABB(const LLVector3& box_min, const LLVector3& box_max); - - void dump(); - - // Scans the pass list and removes any items with an expiration - // time earlier than "now". - void expirePasses(S32 now); - - // Add to list, suppressing duplicates. Returns true if added. - bool addToAccessList(const LLUUID& agent_id, S32 time); - bool addToBanList(const LLUUID& agent_id, S32 time); - bool removeFromAccessList(const LLUUID& agent_id); - bool removeFromBanList(const LLUUID& agent_id); - - // ACCESSORS - const LLUUID& getID() const { return mID; } - const std::string& getName() const { return mName; } - const std::string& getDesc() const { return mDesc; } - const std::string& getMusicURL() const { return mMusicURL; } - const std::string& getMediaURL() const { return mMediaURL; } - const std::string& getMediaDesc() const { return mMediaDesc; } - const std::string& getMediaType() const { return mMediaType; } - const LLUUID& getMediaID() const { return mMediaID; } - S32 getMediaWidth() const { return mMediaWidth; } - S32 getMediaHeight() const { return mMediaHeight; } - U8 getMediaAutoScale() const { return mMediaAutoScale; } - U8 getMediaLoop() const { return mMediaLoop; } - const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; } - U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; } - F32 getMediaURLTimeout() const { return mMediaURLTimeout; } - U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; } - - S32 getLocalID() const { return mLocalID; } - const LLUUID& getOwnerID() const { return mOwnerID; } - const LLUUID& getGroupID() const { return mGroupID; } - S32 getPassPrice() const { return mPassPrice; } - F32 getPassHours() const { return mPassHours; } - bool getIsGroupOwned() const { return mGroupOwned; } - - U32 getAuctionID() const { return mAuctionID; } - bool isInEscrow() const { return mInEscrow; } - - bool isPublic() const; - - // Region-local user-specified position - const LLVector3& getUserLocation() const { return mUserLocation; } - const LLVector3& getUserLookAt() const { return mUserLookAt; } - ELandingType getLandingType() const { return mLandingType; } - bool getSeeAVs() const { return mSeeAVs; } - bool getHaveNewParcelLimitData() const { return mHaveNewParcelLimitData; } - - // User-specified snapshot - const LLUUID& getSnapshotID() const { return mSnapshotID; } - - // the authorized buyer id is the person who is the only - // agent/group that has authority to purchase. (ie, ui specified a - // particular agent could buy the plot). - const LLUUID& getAuthorizedBuyerID() const { return mAuthBuyerID; } - - // helper function - bool isBuyerAuthorized(const LLUUID& buyer_id) const; - - // The buyer of a plot is set when someone indicates they want to - // buy the plot, and the system is simply waiting for tier-up - // approval - //const LLUUID& getBuyerID() const { return mBuyerID; } - - // functions to deal with ownership status. - EOwnershipStatus getOwnershipStatus() const { return mStatus; } - static const std::string& getOwnershipStatusString(EOwnershipStatus status); - void setOwnershipStatus(EOwnershipStatus status) { mStatus = status; } - - // dealing with parcel category information - ECategory getCategory() const {return mCategory; } - static const std::string& getCategoryString(ECategory category); - static const std::string& getCategoryUIString(ECategory category); - static ECategory getCategoryFromString(const std::string& string); - static ECategory getCategoryFromUIString(const std::string& string); - - // functions for parcel action (used for logging) - static const std::string& getActionString(EAction action); - - // dealing with sales and parcel conversion. - // - // the isSaleTimerExpired will trivially return false if there is - // no sale going on. Pass in the current time in usec which will - // be used for comparison. - bool isSaleTimerExpired(const U64& time); - - F32 getSaleTimerExpires() { return mSaleTimerExpires.getRemainingTimeF32(); } - - // should the parcel join on complete? - //U32 getJoinNeighbors() const { return mJoinNeighbors; } - - // need to record a few things with the parcel when a sale - // starts. - void startSale(const LLUUID& buyer_id, bool is_buyer_group); - - // do the expiration logic, which needs to return values usable in - // a L$ transaction. - void expireSale(U32& type, U8& flags, LLUUID& from_id, LLUUID& to_id); - void completeSale(U32& type, U8& flags, LLUUID& to_id); - void clearSale(); - - - bool isMediaResetTimerExpired(const U64& time); - - - // more accessors - U32 getParcelFlags() const { return mParcelFlags; } - - bool getParcelFlag(U32 flag) const { return (mParcelFlags & flag) != 0; } - - // objects can be added or modified by anyone (only parcel owner if disabled) - bool getAllowModify() const { return getParcelFlag(PF_CREATE_OBJECTS); } - - // objects can be added or modified by group members - bool getAllowGroupModify() const { return getParcelFlag(PF_CREATE_GROUP_OBJECTS); } - - // the parcel can be deeded to the group - bool getAllowDeedToGroup() const { return getParcelFlag(PF_ALLOW_DEED_TO_GROUP); } - - // Does the owner want to make a contribution along with the deed. - bool getContributeWithDeed() const { return getParcelFlag(PF_CONTRIBUTE_WITH_DEED); } - - // heightfield can be modified - bool getAllowTerraform() const { return getParcelFlag(PF_ALLOW_TERRAFORM); } - - // avatars can be hurt here - bool getAllowDamage() const { return getParcelFlag(PF_ALLOW_DAMAGE); } - - bool getAllowFly() const { return getParcelFlag(PF_ALLOW_FLY); } - bool getAllowGroupScripts() const { return getParcelFlag(PF_ALLOW_GROUP_SCRIPTS); } - bool getAllowOtherScripts() const { return getParcelFlag(PF_ALLOW_OTHER_SCRIPTS); } - bool getAllowAllObjectEntry() const { return getParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY); } - bool getAllowGroupObjectEntry() const { return getParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY); } - bool getForSale() const { return getParcelFlag(PF_FOR_SALE); } - bool getSoundLocal() const { return getParcelFlag(PF_SOUND_LOCAL); } - bool getParcelFlagAllowVoice() const { return getParcelFlag(PF_ALLOW_VOICE_CHAT); } - bool getParcelFlagUseEstateVoiceChannel() const { return getParcelFlag(PF_USE_ESTATE_VOICE_CHAN); } - bool getAllowPublish() const { return getParcelFlag(PF_ALLOW_PUBLISH); } - bool getMaturePublish() const { return getParcelFlag(PF_MATURE_PUBLISH); } - bool getRestrictPushObject() const { return getParcelFlag(PF_RESTRICT_PUSHOBJECT); } - - bool getRegionPushOverride() const { return mRegionPushOverride; } - bool getRegionDenyAnonymousOverride() const { return mRegionDenyAnonymousOverride; } - bool getRegionDenyAgeUnverifiedOverride() const { return mRegionDenyAgeUnverifiedOverride; } - bool getRegionAllowAccessOverride() const { return mRegionAllowAccessoverride; } - bool getRegionAllowEnvironmentOverride() const { return mRegionAllowEnvironmentOverride; } - S32 getParcelEnvironmentVersion() const { return mCurrentEnvironmentVersion; } - bool getAllowGroupAVSounds() const { return mAllowGroupAVSounds; } - bool getAllowAnyAVSounds() const { return mAllowAnyAVSounds; } - bool getObscureMOAP() const { return mObscureMOAP; } - - F32 getDrawDistance() const { return mDrawDistance; } - S32 getSalePrice() const { return mSalePrice; } - time_t getClaimDate() const { return mClaimDate; } - S32 getClaimPricePerMeter() const { return mClaimPricePerMeter; } - S32 getRentPricePerMeter() const { return mRentPricePerMeter; } - - // Area is NOT automatically calculated. You must calculate it - // and store it with setArea. - S32 getArea() const { return mArea; } - - // deprecated 12/11/2003 - //F32 getDiscountRate() const { return mDiscountRate; } - - S32 getClaimPrice() const { return mClaimPricePerMeter * mArea; } - - // Can this agent create objects here? - bool allowModifyBy(const LLUUID &agent_id, const LLUUID &group_id) const; - - // Can this agent change the shape of the land? - bool allowTerraformBy(const LLUUID &agent_id) const; - - bool operator==(const LLParcel &rhs) const; - - // Calculate rent - area * rent * discount rate - S32 getTotalRent() const; - F32 getAdjustedRentPerMeter() const; - - const LLVector3& getAABBMin() const { return mAABBMin; } - const LLVector3& getAABBMax() const { return mAABBMax; } - LLVector3 getCenterpoint() const; - - // simwide - S32 getSimWideMaxPrimCapacity() const { return mSimWideMaxPrimCapacity; } - S32 getSimWidePrimCount() const { return mSimWidePrimCount; } - - // this parcel only (not simwide) - S32 getMaxPrimCapacity() const { return mMaxPrimCapacity; } // Does not include prim bonus - S32 getPrimCount() const { return mOwnerPrimCount + mGroupPrimCount + mOtherPrimCount + mSelectedPrimCount; } - S32 getOwnerPrimCount() const { return mOwnerPrimCount; } - S32 getGroupPrimCount() const { return mGroupPrimCount; } - S32 getOtherPrimCount() const { return mOtherPrimCount; } - S32 getSelectedPrimCount() const{ return mSelectedPrimCount; } - S32 getTempPrimCount() const { return mTempPrimCount; } - F32 getParcelPrimBonus() const { return mParcelPrimBonus; } - - S32 getCleanOtherTime() const { return mCleanOtherTime; } - - void setMaxPrimCapacity(S32 max) { mMaxPrimCapacity = max; } // Does not include prim bonus - // simwide - void setSimWideMaxPrimCapacity(S32 current) { mSimWideMaxPrimCapacity = current; } - void setSimWidePrimCount(S32 current) { mSimWidePrimCount = current; } - - // this parcel only (not simwide) - void setOwnerPrimCount(S32 current) { mOwnerPrimCount = current; } - void setGroupPrimCount(S32 current) { mGroupPrimCount = current; } - void setOtherPrimCount(S32 current) { mOtherPrimCount = current; } - void setSelectedPrimCount(S32 current) { mSelectedPrimCount = current; } - void setTempPrimCount(S32 current) { mTempPrimCount = current; } - void setParcelPrimBonus(F32 bonus) { mParcelPrimBonus = bonus; } - - void setCleanOtherTime(S32 time) { mCleanOtherTime = time; } - void setRegionPushOverride(bool override) {mRegionPushOverride = override; } - void setRegionDenyAnonymousOverride(bool override) { mRegionDenyAnonymousOverride = override; } - void setRegionDenyAgeUnverifiedOverride(bool override) { mRegionDenyAgeUnverifiedOverride = override; } - void setRegionAllowAccessOverride(bool override) { mRegionAllowAccessoverride = override; } - void setRegionAllowEnvironmentOverride(bool override) { mRegionAllowEnvironmentOverride = override; } - - void setParcelEnvironmentVersion(S32 version) { mCurrentEnvironmentVersion = version; } - - // Accessors for parcel sellWithObjects - void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; } - void setPreviouslyGroupOwned(bool b) { mPreviouslyGroupOwned = b; } - void setSellWithObjects(bool b) { setParcelFlag(PF_SELL_PARCEL_OBJECTS, b); } - - LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; } - bool getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } - bool getSellWithObjects() const { return getParcelFlag(PF_SELL_PARCEL_OBJECTS); } - -protected: - LLUUID mID; - LLUUID mOwnerID; - LLUUID mGroupID; - bool mGroupOwned; // true if mOwnerID is a group_id - LLUUID mPreviousOwnerID; - bool mPreviouslyGroupOwned; - - EOwnershipStatus mStatus; - ECategory mCategory; - LLUUID mAuthBuyerID; - LLUUID mSnapshotID; - LLVector3 mUserLocation; - LLVector3 mUserLookAt; - ELandingType mLandingType; - bool mSeeAVs; // Avatars on this parcel are visible from outside it - bool mHaveNewParcelLimitData; // Remove once hidden AV feature is grid-wide - LLTimer mSaleTimerExpires; - LLTimer mMediaResetTimer; - - S32 mGraceExtension; - - // This value is non-zero if there is an auction associated with - // the parcel. - U32 mAuctionID; - - // value used to temporarily lock attempts to purchase the parcel. - bool mInEscrow; - - time_t mClaimDate; // UTC Unix-format time - S32 mClaimPricePerMeter; // meter squared - S32 mRentPricePerMeter; // meter squared - S32 mArea; // meter squared - F32 mDiscountRate; // 0.0-1.0 - F32 mDrawDistance; - U32 mParcelFlags; - S32 mSalePrice; // linden dollars - std::string mName; - std::string mDesc; - std::string mMusicURL; - std::string mMediaURL; - std::string mMediaDesc; - std::string mMediaType; - S32 mMediaWidth; - S32 mMediaHeight; - U8 mMediaAutoScale; - U8 mMediaLoop; - std::string mMediaCurrentURL; - LLUUID mMediaID; - U8 mMediaAllowNavigate; - U8 mMediaPreventCameraZoom; - F32 mMediaURLTimeout; - S32 mPassPrice; - F32 mPassHours; - LLVector3 mAABBMin; - LLVector3 mAABBMax; - S32 mMaxPrimCapacity; // Prims allowed on parcel, does not include prim bonus - S32 mSimWidePrimCount; - S32 mSimWideMaxPrimCapacity; - //S32 mSimWidePrimCorrection; - S32 mOwnerPrimCount; - S32 mGroupPrimCount; - S32 mOtherPrimCount; - S32 mSelectedPrimCount; - S32 mTempPrimCount; - F32 mParcelPrimBonus; - S32 mCleanOtherTime; - bool mRegionPushOverride; - bool mRegionDenyAnonymousOverride; - bool mRegionDenyAgeUnverifiedOverride; - bool mRegionAllowAccessoverride; - bool mRegionAllowEnvironmentOverride; - bool mAllowGroupAVSounds; - bool mAllowAnyAVSounds; - bool mObscureMOAP; - S32 mCurrentEnvironmentVersion; - - bool mIsDefaultDayCycle; - -public: - // HACK, make private - S32 mLocalID; - LLUUID mBanListTransactionID; - LLUUID mAccessListTransactionID; - std::map<LLUUID,LLAccessEntry> mAccessList; - std::map<LLUUID,LLAccessEntry> mBanList; - std::map<LLUUID,LLAccessEntry> mTempBanList; - std::map<LLUUID,LLAccessEntry> mTempAccessList; - - typedef std::map<LLUUID, U32> xp_type_map_t; - - void setExperienceKeyType(const LLUUID& experience_key, U32 type); - U32 countExperienceKeyType(U32 type); - LLAccessEntry::map getExperienceKeysByType(U32 type)const; - void clearExperienceKeysByType(U32 type); - -private: - xp_type_map_t mExperienceKeys; -}; - - -const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status); -LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s); -LLParcel::ECategory category_string_to_category(const std::string& s); -const std::string& category_to_string(LLParcel::ECategory category); - - -#endif +/**
+ * @file llparcel.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPARCEL_H
+#define LL_LLPARCEL_H
+
+#include <time.h>
+#include <iostream>
+
+#include "lluuid.h"
+#include "llparcelflags.h"
+#include "llpermissions.h"
+#include "lltimer.h"
+#include "v3math.h"
+#include "llsettingsdaycycle.h"
+
+// Grid out of which parcels taken is stepped every 4 meters.
+const F32 PARCEL_GRID_STEP_METERS = 4.f;
+
+// Area of one "square" of parcel
+const S32 PARCEL_UNIT_AREA = 16;
+
+// Height _above_ground_ that parcel boundary ends
+const F32 PARCEL_HEIGHT = 50.f;
+
+//Height above ground which parcel boundries exist for explicitly banned avatars
+const F32 BAN_HEIGHT = 5000.f;
+
+// Maximum number of entries in an access list
+const S32 PARCEL_MAX_ACCESS_LIST = 300;
+//Maximum number of entires in an update packet
+//for access/ban lists.
+const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
+
+// Maximum number of experiences
+const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
+
+// Weekly charge for listing a parcel in the directory
+const S32 PARCEL_DIRECTORY_FEE = 30;
+
+const S32 PARCEL_PASS_PRICE_DEFAULT = 10;
+const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f;
+
+// Number of "chunks" in which parcel overlay data is sent
+// Chunk 0 = southern rows, entire width
+const S32 PARCEL_OVERLAY_CHUNKS = 4;
+
+// Bottom three bits are a color index for the land overlay
+const U8 PARCEL_COLOR_MASK = 0x07;
+const U8 PARCEL_PUBLIC = 0x00;
+const U8 PARCEL_OWNED = 0x01;
+const U8 PARCEL_GROUP = 0x02;
+const U8 PARCEL_SELF = 0x03;
+const U8 PARCEL_FOR_SALE = 0x04;
+const U8 PARCEL_AUCTION = 0x05;
+// unused 0x06
+// unused 0x07
+// flag, unused 0x08
+const U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility
+const U8 PARCEL_SOUND_LOCAL = 0x20;
+const U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge
+const U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge
+
+// Transmission results for parcel properties
+const S32 PARCEL_RESULT_NO_DATA = -1;
+const S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel
+const S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels
+
+const S32 SELECTED_PARCEL_SEQ_ID = -10000;
+const S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000;
+const S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000;
+const S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000;
+const S32 HOVERED_PARCEL_SEQ_ID = -50000;
+
+const U32 RT_NONE = 0x1 << 0;
+const U32 RT_OWNER = 0x1 << 1;
+const U32 RT_GROUP = 0x1 << 2;
+const U32 RT_OTHER = 0x1 << 3;
+const U32 RT_LIST = 0x1 << 4;
+const U32 RT_SELL = 0x1 << 5;
+
+const S32 INVALID_PARCEL_ID = -1;
+
+const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;
+// if Region settings are used, parcel env. version is -1
+const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;
+
+// Timeouts for parcels
+// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
+const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
+// ***** TESTING is 10 minutes
+//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000);
+
+// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000
+const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);
+// ***** TESTING is 10 minutes
+//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000);
+
+// default sale timeout is 2 days -> 172800000000
+const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);
+// ***** TESTING is 10 minutes
+//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000);
+
+// more grace period extensions.
+const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);
+
+// if more than 100,000s before sale revert, and no extra extension
+// has been given, go ahead and extend it more. That's about 1.2 days.
+const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000;
+
+
+
+class LLMessageSystem;
+class LLSD;
+
+class LLAccessEntry
+{
+public:
+
+ typedef std::map<LLUUID,LLAccessEntry> map;
+
+ LLAccessEntry()
+ : mTime(0),
+ mFlags(0)
+ {}
+
+ LLUUID mID; // Agent ID
+ S32 mTime; // Time (unix seconds) when entry expires
+ U32 mFlags; // Not used - currently should always be zero
+};
+
+
+class LLParcel
+{
+public:
+ enum EOwnershipStatus
+ {
+ OS_LEASED = 0,
+ OS_LEASE_PENDING = 1,
+ OS_ABANDONED = 2,
+ OS_COUNT = 3,
+ OS_NONE = -1
+ };
+ enum ECategory
+ {
+ C_NONE = 0,
+ C_LINDEN,
+ C_ADULT,
+ C_ARTS, // "arts & culture"
+ C_BUSINESS, // was "store"
+ C_EDUCATIONAL,
+ C_GAMING, // was "game"
+ C_HANGOUT, // was "gathering place"
+ C_NEWCOMER,
+ C_PARK, // "parks & nature"
+ C_RESIDENTIAL, // was "homestead"
+ C_SHOPPING,
+ C_STAGE,
+ C_OTHER,
+ C_RENTAL,
+ C_COUNT,
+ C_ANY = -1 // only useful in queries
+ };
+ enum EAction
+ {
+ A_CREATE = 0,
+ A_RELEASE = 1,
+ A_ABSORB = 2,
+ A_ABSORBED = 3,
+ A_DIVIDE = 4,
+ A_DIVISION = 5,
+ A_ACQUIRE = 6,
+ A_RELINQUISH = 7,
+ A_CONFIRM = 8,
+ A_COUNT = 9,
+ A_UNKNOWN = -1
+ };
+
+ enum ELandingType
+ {
+ L_NONE = 0,
+ L_LANDING_POINT = 1,
+ L_DIRECT = 2
+ };
+
+ // CREATORS
+ LLParcel();
+ LLParcel(
+ const LLUUID &owner_id,
+ bool modify,
+ bool terraform,
+ bool damage,
+ time_t claim_date,
+ S32 claim_price,
+ S32 rent_price,
+ S32 area,
+ S32 sim_object_limit,
+ F32 parcel_object_bonus,
+ bool is_group_owned = false);
+ virtual ~LLParcel();
+
+ void init(
+ const LLUUID &owner_id,
+ bool modify,
+ bool terraform,
+ bool damage,
+ time_t claim_date,
+ S32 claim_price,
+ S32 rent_price,
+ S32 area,
+ S32 sim_object_limit,
+ F32 parcel_object_bonus,
+ bool is_group_owned = false);
+
+ // TODO: make an actual copy constructor for this
+ void overrideParcelFlags(U32 flags);
+ // if you specify an agent id here, the group id will be zeroed
+ void overrideOwner(
+ const LLUUID& owner_id,
+ bool is_group_owned = false);
+ void overrideSaleTimerExpires(F32 secs_left) { mSaleTimerExpires.setTimerExpirySec(secs_left); }
+
+ // MANIPULATORS
+ void generateNewID() { mID.generate(); }
+ void setName(const std::string& name);
+ void setDesc(const std::string& desc);
+ void setMusicURL(const std::string& url);
+ void setMediaURL(const std::string& url);
+ void setMediaType(const std::string& type);
+ void setMediaDesc(const std::string& desc);
+ void setMediaID(const LLUUID& id) { mMediaID = id; }
+ void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; }
+ void setMediaLoop (U8 loop) { mMediaLoop = loop; }
+ void setMediaWidth(S32 width);
+ void setMediaHeight(S32 height);
+ void setMediaCurrentURL(const std::string& url);
+ void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; }
+ void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; }
+ void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; }
+
+ void setMediaURLResetTimer(F32 time);
+ virtual void setLocalID(S32 local_id);
+
+ // blow away all the extra stuff lurking in parcels, including urls, access lists, etc
+ void clearParcel();
+
+ // This value is not persisted out to the parcel file, it is only
+ // a per-process blocker for attempts to purchase.
+ void setInEscrow(bool in_escrow) { mInEscrow = in_escrow; }
+
+ void setAuthorizedBuyerID(const LLUUID& id) { mAuthBuyerID = id; }
+ //void overrideBuyerID(const LLUUID& id) { mBuyerID = id; }
+ void setCategory(ECategory category) { mCategory = category; }
+ void setSnapshotID(const LLUUID& id) { mSnapshotID = id; }
+ void setUserLocation(const LLVector3& pos) { mUserLocation = pos; }
+ void setUserLookAt(const LLVector3& rot) { mUserLookAt = rot; }
+ void setLandingType(const ELandingType type) { mLandingType = type; }
+ void setSeeAVs(bool see_avs) { mSeeAVs = see_avs; }
+ void setHaveNewParcelLimitData(bool have_new_parcel_data) { mHaveNewParcelLimitData = have_new_parcel_data; } // Remove this once hidden AV feature is fully available grid-wide
+
+ void setAuctionID(U32 auction_id) { mAuctionID = auction_id;}
+
+ void setAllParcelFlags(U32 flags);
+ void setParcelFlag(U32 flag, bool b);
+
+ virtual void setArea(S32 area, S32 sim_object_limit);
+ void setDiscountRate(F32 rate);
+
+ void setAllowModify(bool b) { setParcelFlag(PF_CREATE_OBJECTS, b); }
+ void setAllowGroupModify(bool b) { setParcelFlag(PF_CREATE_GROUP_OBJECTS, b); }
+ void setAllowAllObjectEntry(bool b) { setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, b); }
+ void setAllowGroupObjectEntry(bool b) { setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, b); }
+ void setAllowTerraform(bool b){setParcelFlag(PF_ALLOW_TERRAFORM, b); }
+ void setAllowDamage(bool b) { setParcelFlag(PF_ALLOW_DAMAGE, b); }
+ void setAllowFly(bool b) { setParcelFlag(PF_ALLOW_FLY, b); }
+ void setAllowGroupScripts(bool b) { setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); }
+ void setAllowOtherScripts(bool b) { setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); }
+ void setAllowDeedToGroup(bool b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); }
+ void setContributeWithDeed(bool b) { setParcelFlag(PF_CONTRIBUTE_WITH_DEED, b); }
+ void setForSale(bool b) { setParcelFlag(PF_FOR_SALE, b); }
+ void setSoundOnly(bool b) { setParcelFlag(PF_SOUND_LOCAL, b); }
+ void setDenyAnonymous(bool b) { setParcelFlag(PF_DENY_ANONYMOUS, b); }
+ void setDenyAgeUnverified(bool b) { setParcelFlag(PF_DENY_AGEUNVERIFIED, b); }
+ void setRestrictPushObject(bool b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); }
+ void setAllowGroupAVSounds(bool b) { mAllowGroupAVSounds = b; }
+ void setAllowAnyAVSounds(bool b) { mAllowAnyAVSounds = b; }
+ void setObscureMOAP(bool b) { mObscureMOAP = b; }
+
+ void setDrawDistance(F32 dist) { mDrawDistance = dist; }
+ void setSalePrice(S32 price) { mSalePrice = price; }
+ void setGroupID(const LLUUID& id) { mGroupID = id; }
+ //void setGroupName(const std::string& s) { mGroupName.assign(s); }
+ void setPassPrice(S32 price) { mPassPrice = price; }
+ void setPassHours(F32 hours) { mPassHours = hours; }
+
+// bool importStream(std::istream& input_stream);
+ bool importAccessEntry(std::istream& input_stream, LLAccessEntry* entry);
+ // bool exportStream(std::ostream& output_stream);
+
+ void packMessage(LLMessageSystem* msg);
+ void packMessage(LLSD& msg);
+ void unpackMessage(LLMessageSystem* msg);
+
+ void packAccessEntries(LLMessageSystem* msg,
+ const std::map<LLUUID,LLAccessEntry>& list);
+ void unpackAccessEntries(LLMessageSystem* msg,
+ std::map<LLUUID,LLAccessEntry>* list);
+
+ void unpackExperienceEntries(LLMessageSystem* msg, U32 type);
+
+
+ void setAABBMin(const LLVector3& min) { mAABBMin = min; }
+ void setAABBMax(const LLVector3& max) { mAABBMax = max; }
+
+ // Extend AABB to include rectangle from min to max.
+ void extendAABB(const LLVector3& box_min, const LLVector3& box_max);
+
+ void dump();
+
+ // Scans the pass list and removes any items with an expiration
+ // time earlier than "now".
+ void expirePasses(S32 now);
+
+ // Add to list, suppressing duplicates. Returns true if added.
+ bool addToAccessList(const LLUUID& agent_id, S32 time);
+ bool addToBanList(const LLUUID& agent_id, S32 time);
+ bool removeFromAccessList(const LLUUID& agent_id);
+ bool removeFromBanList(const LLUUID& agent_id);
+
+ // ACCESSORS
+ const LLUUID& getID() const { return mID; }
+ const std::string& getName() const { return mName; }
+ const std::string& getDesc() const { return mDesc; }
+ const std::string& getMusicURL() const { return mMusicURL; }
+ const std::string& getMediaURL() const { return mMediaURL; }
+ const std::string& getMediaDesc() const { return mMediaDesc; }
+ const std::string& getMediaType() const { return mMediaType; }
+ const LLUUID& getMediaID() const { return mMediaID; }
+ S32 getMediaWidth() const { return mMediaWidth; }
+ S32 getMediaHeight() const { return mMediaHeight; }
+ U8 getMediaAutoScale() const { return mMediaAutoScale; }
+ U8 getMediaLoop() const { return mMediaLoop; }
+ const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; }
+ U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; }
+ F32 getMediaURLTimeout() const { return mMediaURLTimeout; }
+ U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; }
+
+ S32 getLocalID() const { return mLocalID; }
+ const LLUUID& getOwnerID() const { return mOwnerID; }
+ const LLUUID& getGroupID() const { return mGroupID; }
+ S32 getPassPrice() const { return mPassPrice; }
+ F32 getPassHours() const { return mPassHours; }
+ bool getIsGroupOwned() const { return mGroupOwned; }
+
+ U32 getAuctionID() const { return mAuctionID; }
+ bool isInEscrow() const { return mInEscrow; }
+
+ bool isPublic() const;
+
+ // Region-local user-specified position
+ const LLVector3& getUserLocation() const { return mUserLocation; }
+ const LLVector3& getUserLookAt() const { return mUserLookAt; }
+ ELandingType getLandingType() const { return mLandingType; }
+ bool getSeeAVs() const { return mSeeAVs; }
+ bool getHaveNewParcelLimitData() const { return mHaveNewParcelLimitData; }
+
+ // User-specified snapshot
+ const LLUUID& getSnapshotID() const { return mSnapshotID; }
+
+ // the authorized buyer id is the person who is the only
+ // agent/group that has authority to purchase. (ie, ui specified a
+ // particular agent could buy the plot).
+ const LLUUID& getAuthorizedBuyerID() const { return mAuthBuyerID; }
+
+ // helper function
+ bool isBuyerAuthorized(const LLUUID& buyer_id) const;
+
+ // The buyer of a plot is set when someone indicates they want to
+ // buy the plot, and the system is simply waiting for tier-up
+ // approval
+ //const LLUUID& getBuyerID() const { return mBuyerID; }
+
+ // functions to deal with ownership status.
+ EOwnershipStatus getOwnershipStatus() const { return mStatus; }
+ static const std::string& getOwnershipStatusString(EOwnershipStatus status);
+ void setOwnershipStatus(EOwnershipStatus status) { mStatus = status; }
+
+ // dealing with parcel category information
+ ECategory getCategory() const {return mCategory; }
+ static const std::string& getCategoryString(ECategory category);
+ static const std::string& getCategoryUIString(ECategory category);
+ static ECategory getCategoryFromString(const std::string& string);
+ static ECategory getCategoryFromUIString(const std::string& string);
+
+ // functions for parcel action (used for logging)
+ static const std::string& getActionString(EAction action);
+
+ // dealing with sales and parcel conversion.
+ //
+ // the isSaleTimerExpired will trivially return false if there is
+ // no sale going on. Pass in the current time in usec which will
+ // be used for comparison.
+ bool isSaleTimerExpired(const U64& time);
+
+ F32 getSaleTimerExpires() { return mSaleTimerExpires.getRemainingTimeF32(); }
+
+ // should the parcel join on complete?
+ //U32 getJoinNeighbors() const { return mJoinNeighbors; }
+
+ // need to record a few things with the parcel when a sale
+ // starts.
+ void startSale(const LLUUID& buyer_id, bool is_buyer_group);
+
+ // do the expiration logic, which needs to return values usable in
+ // a L$ transaction.
+ void expireSale(U32& type, U8& flags, LLUUID& from_id, LLUUID& to_id);
+ void completeSale(U32& type, U8& flags, LLUUID& to_id);
+ void clearSale();
+
+
+ bool isMediaResetTimerExpired(const U64& time);
+
+
+ // more accessors
+ U32 getParcelFlags() const { return mParcelFlags; }
+
+ bool getParcelFlag(U32 flag) const { return (mParcelFlags & flag) != 0; }
+
+ // objects can be added or modified by anyone (only parcel owner if disabled)
+ bool getAllowModify() const { return getParcelFlag(PF_CREATE_OBJECTS); }
+
+ // objects can be added or modified by group members
+ bool getAllowGroupModify() const { return getParcelFlag(PF_CREATE_GROUP_OBJECTS); }
+
+ // the parcel can be deeded to the group
+ bool getAllowDeedToGroup() const { return getParcelFlag(PF_ALLOW_DEED_TO_GROUP); }
+
+ // Does the owner want to make a contribution along with the deed.
+ bool getContributeWithDeed() const { return getParcelFlag(PF_CONTRIBUTE_WITH_DEED); }
+
+ // heightfield can be modified
+ bool getAllowTerraform() const { return getParcelFlag(PF_ALLOW_TERRAFORM); }
+
+ // avatars can be hurt here
+ bool getAllowDamage() const { return getParcelFlag(PF_ALLOW_DAMAGE); }
+
+ bool getAllowFly() const { return getParcelFlag(PF_ALLOW_FLY); }
+ bool getAllowGroupScripts() const { return getParcelFlag(PF_ALLOW_GROUP_SCRIPTS); }
+ bool getAllowOtherScripts() const { return getParcelFlag(PF_ALLOW_OTHER_SCRIPTS); }
+ bool getAllowAllObjectEntry() const { return getParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY); }
+ bool getAllowGroupObjectEntry() const { return getParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY); }
+ bool getForSale() const { return getParcelFlag(PF_FOR_SALE); }
+ bool getSoundLocal() const { return getParcelFlag(PF_SOUND_LOCAL); }
+ bool getParcelFlagAllowVoice() const { return getParcelFlag(PF_ALLOW_VOICE_CHAT); }
+ bool getParcelFlagUseEstateVoiceChannel() const { return getParcelFlag(PF_USE_ESTATE_VOICE_CHAN); }
+ bool getAllowPublish() const { return getParcelFlag(PF_ALLOW_PUBLISH); }
+ bool getMaturePublish() const { return getParcelFlag(PF_MATURE_PUBLISH); }
+ bool getRestrictPushObject() const { return getParcelFlag(PF_RESTRICT_PUSHOBJECT); }
+
+ bool getRegionPushOverride() const { return mRegionPushOverride; }
+ bool getRegionDenyAnonymousOverride() const { return mRegionDenyAnonymousOverride; }
+ bool getRegionDenyAgeUnverifiedOverride() const { return mRegionDenyAgeUnverifiedOverride; }
+ bool getRegionAllowAccessOverride() const { return mRegionAllowAccessoverride; }
+ bool getRegionAllowEnvironmentOverride() const { return mRegionAllowEnvironmentOverride; }
+ S32 getParcelEnvironmentVersion() const { return mCurrentEnvironmentVersion; }
+ bool getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
+ bool getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
+ bool getObscureMOAP() const { return mObscureMOAP; }
+
+ F32 getDrawDistance() const { return mDrawDistance; }
+ S32 getSalePrice() const { return mSalePrice; }
+ time_t getClaimDate() const { return mClaimDate; }
+ S32 getClaimPricePerMeter() const { return mClaimPricePerMeter; }
+ S32 getRentPricePerMeter() const { return mRentPricePerMeter; }
+
+ // Area is NOT automatically calculated. You must calculate it
+ // and store it with setArea.
+ S32 getArea() const { return mArea; }
+
+ // deprecated 12/11/2003
+ //F32 getDiscountRate() const { return mDiscountRate; }
+
+ S32 getClaimPrice() const { return mClaimPricePerMeter * mArea; }
+
+ // Can this agent create objects here?
+ bool allowModifyBy(const LLUUID &agent_id, const LLUUID &group_id) const;
+
+ // Can this agent change the shape of the land?
+ bool allowTerraformBy(const LLUUID &agent_id) const;
+
+ bool operator==(const LLParcel &rhs) const;
+
+ // Calculate rent - area * rent * discount rate
+ S32 getTotalRent() const;
+ F32 getAdjustedRentPerMeter() const;
+
+ const LLVector3& getAABBMin() const { return mAABBMin; }
+ const LLVector3& getAABBMax() const { return mAABBMax; }
+ LLVector3 getCenterpoint() const;
+
+ // simwide
+ S32 getSimWideMaxPrimCapacity() const { return mSimWideMaxPrimCapacity; }
+ S32 getSimWidePrimCount() const { return mSimWidePrimCount; }
+
+ // this parcel only (not simwide)
+ S32 getMaxPrimCapacity() const { return mMaxPrimCapacity; } // Does not include prim bonus
+ S32 getPrimCount() const { return mOwnerPrimCount + mGroupPrimCount + mOtherPrimCount + mSelectedPrimCount; }
+ S32 getOwnerPrimCount() const { return mOwnerPrimCount; }
+ S32 getGroupPrimCount() const { return mGroupPrimCount; }
+ S32 getOtherPrimCount() const { return mOtherPrimCount; }
+ S32 getSelectedPrimCount() const{ return mSelectedPrimCount; }
+ S32 getTempPrimCount() const { return mTempPrimCount; }
+ F32 getParcelPrimBonus() const { return mParcelPrimBonus; }
+
+ S32 getCleanOtherTime() const { return mCleanOtherTime; }
+
+ void setMaxPrimCapacity(S32 max) { mMaxPrimCapacity = max; } // Does not include prim bonus
+ // simwide
+ void setSimWideMaxPrimCapacity(S32 current) { mSimWideMaxPrimCapacity = current; }
+ void setSimWidePrimCount(S32 current) { mSimWidePrimCount = current; }
+
+ // this parcel only (not simwide)
+ void setOwnerPrimCount(S32 current) { mOwnerPrimCount = current; }
+ void setGroupPrimCount(S32 current) { mGroupPrimCount = current; }
+ void setOtherPrimCount(S32 current) { mOtherPrimCount = current; }
+ void setSelectedPrimCount(S32 current) { mSelectedPrimCount = current; }
+ void setTempPrimCount(S32 current) { mTempPrimCount = current; }
+ void setParcelPrimBonus(F32 bonus) { mParcelPrimBonus = bonus; }
+
+ void setCleanOtherTime(S32 time) { mCleanOtherTime = time; }
+ void setRegionPushOverride(bool override) {mRegionPushOverride = override; }
+ void setRegionDenyAnonymousOverride(bool override) { mRegionDenyAnonymousOverride = override; }
+ void setRegionDenyAgeUnverifiedOverride(bool override) { mRegionDenyAgeUnverifiedOverride = override; }
+ void setRegionAllowAccessOverride(bool override) { mRegionAllowAccessoverride = override; }
+ void setRegionAllowEnvironmentOverride(bool override) { mRegionAllowEnvironmentOverride = override; }
+
+ void setParcelEnvironmentVersion(S32 version) { mCurrentEnvironmentVersion = version; }
+
+ // Accessors for parcel sellWithObjects
+ void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; }
+ void setPreviouslyGroupOwned(bool b) { mPreviouslyGroupOwned = b; }
+ void setSellWithObjects(bool b) { setParcelFlag(PF_SELL_PARCEL_OBJECTS, b); }
+
+ LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; }
+ bool getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
+ bool getSellWithObjects() const { return getParcelFlag(PF_SELL_PARCEL_OBJECTS); }
+
+protected:
+ LLUUID mID;
+ LLUUID mOwnerID;
+ LLUUID mGroupID;
+ bool mGroupOwned; // true if mOwnerID is a group_id
+ LLUUID mPreviousOwnerID;
+ bool mPreviouslyGroupOwned;
+
+ EOwnershipStatus mStatus;
+ ECategory mCategory;
+ LLUUID mAuthBuyerID;
+ LLUUID mSnapshotID;
+ LLVector3 mUserLocation;
+ LLVector3 mUserLookAt;
+ ELandingType mLandingType;
+ bool mSeeAVs; // Avatars on this parcel are visible from outside it
+ bool mHaveNewParcelLimitData; // Remove once hidden AV feature is grid-wide
+ LLTimer mSaleTimerExpires;
+ LLTimer mMediaResetTimer;
+
+ S32 mGraceExtension;
+
+ // This value is non-zero if there is an auction associated with
+ // the parcel.
+ U32 mAuctionID;
+
+ // value used to temporarily lock attempts to purchase the parcel.
+ bool mInEscrow;
+
+ time_t mClaimDate; // UTC Unix-format time
+ S32 mClaimPricePerMeter; // meter squared
+ S32 mRentPricePerMeter; // meter squared
+ S32 mArea; // meter squared
+ F32 mDiscountRate; // 0.0-1.0
+ F32 mDrawDistance;
+ U32 mParcelFlags;
+ S32 mSalePrice; // linden dollars
+ std::string mName;
+ std::string mDesc;
+ std::string mMusicURL;
+ std::string mMediaURL;
+ std::string mMediaDesc;
+ std::string mMediaType;
+ S32 mMediaWidth;
+ S32 mMediaHeight;
+ U8 mMediaAutoScale;
+ U8 mMediaLoop;
+ std::string mMediaCurrentURL;
+ LLUUID mMediaID;
+ U8 mMediaAllowNavigate;
+ U8 mMediaPreventCameraZoom;
+ F32 mMediaURLTimeout;
+ S32 mPassPrice;
+ F32 mPassHours;
+ LLVector3 mAABBMin;
+ LLVector3 mAABBMax;
+ S32 mMaxPrimCapacity; // Prims allowed on parcel, does not include prim bonus
+ S32 mSimWidePrimCount;
+ S32 mSimWideMaxPrimCapacity;
+ //S32 mSimWidePrimCorrection;
+ S32 mOwnerPrimCount;
+ S32 mGroupPrimCount;
+ S32 mOtherPrimCount;
+ S32 mSelectedPrimCount;
+ S32 mTempPrimCount;
+ F32 mParcelPrimBonus;
+ S32 mCleanOtherTime;
+ bool mRegionPushOverride;
+ bool mRegionDenyAnonymousOverride;
+ bool mRegionDenyAgeUnverifiedOverride;
+ bool mRegionAllowAccessoverride;
+ bool mRegionAllowEnvironmentOverride;
+ bool mAllowGroupAVSounds;
+ bool mAllowAnyAVSounds;
+ bool mObscureMOAP;
+ S32 mCurrentEnvironmentVersion;
+
+ bool mIsDefaultDayCycle;
+
+public:
+ // HACK, make private
+ S32 mLocalID;
+ LLUUID mBanListTransactionID;
+ LLUUID mAccessListTransactionID;
+ std::map<LLUUID,LLAccessEntry> mAccessList;
+ std::map<LLUUID,LLAccessEntry> mBanList;
+ std::map<LLUUID,LLAccessEntry> mTempBanList;
+ std::map<LLUUID,LLAccessEntry> mTempAccessList;
+
+ typedef std::map<LLUUID, U32> xp_type_map_t;
+
+ void setExperienceKeyType(const LLUUID& experience_key, U32 type);
+ U32 countExperienceKeyType(U32 type);
+ LLAccessEntry::map getExperienceKeysByType(U32 type)const;
+ void clearExperienceKeysByType(U32 type);
+
+private:
+ xp_type_map_t mExperienceKeys;
+};
+
+
+const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status);
+LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s);
+LLParcel::ECategory category_string_to_category(const std::string& s);
+const std::string& category_to_string(LLParcel::ECategory category);
+
+
+#endif
diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h index 4cffa83cc1..25f8ae1984 100644 --- a/indra/llinventory/llparcelflags.h +++ b/indra/llinventory/llparcelflags.h @@ -1,24 +1,24 @@ -/** +/** * @file llparcelflags.h * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,71 +29,71 @@ //--------------------------------------------------------------------------- // Parcel Flags (PF) constants //--------------------------------------------------------------------------- -const U32 PF_ALLOW_FLY = 1 << 0;// Can start flying +const U32 PF_ALLOW_FLY = 1 << 0;// Can start flying const U32 PF_ALLOW_OTHER_SCRIPTS= 1 << 1;// Scripts by others can run. -const U32 PF_FOR_SALE = 1 << 2;// Can buy this land -const U32 PF_FOR_SALE_OBJECTS = 1 << 7;// Can buy all objects on this land -const U32 PF_ALLOW_LANDMARK = 1 << 3;// Always true/deprecated -const U32 PF_ALLOW_TERRAFORM = 1 << 4; -const U32 PF_ALLOW_DAMAGE = 1 << 5; -const U32 PF_CREATE_OBJECTS = 1 << 6; +const U32 PF_FOR_SALE = 1 << 2;// Can buy this land +const U32 PF_FOR_SALE_OBJECTS = 1 << 7;// Can buy all objects on this land +const U32 PF_ALLOW_LANDMARK = 1 << 3;// Always true/deprecated +const U32 PF_ALLOW_TERRAFORM = 1 << 4; +const U32 PF_ALLOW_DAMAGE = 1 << 5; +const U32 PF_CREATE_OBJECTS = 1 << 6; // 7 is moved above -const U32 PF_USE_ACCESS_GROUP = 1 << 8; -const U32 PF_USE_ACCESS_LIST = 1 << 9; -const U32 PF_USE_BAN_LIST = 1 << 10; -const U32 PF_USE_PASS_LIST = 1 << 11; -const U32 PF_SHOW_DIRECTORY = 1 << 12; -const U32 PF_ALLOW_DEED_TO_GROUP = 1 << 13; -const U32 PF_CONTRIBUTE_WITH_DEED = 1 << 14; -const U32 PF_SOUND_LOCAL = 1 << 15; // Hear sounds in this parcel only -const U32 PF_SELL_PARCEL_OBJECTS = 1 << 16; // Objects on land are included as part of the land when the land is sold -const U32 PF_ALLOW_PUBLISH = 1 << 17; // Allow publishing of parcel information on the web -const U32 PF_MATURE_PUBLISH = 1 << 18; // The information on this parcel is mature -const U32 PF_URL_WEB_PAGE = 1 << 19; // The "media URL" is an HTML page -const U32 PF_URL_RAW_HTML = 1 << 20; // The "media URL" is a raw HTML string like <H1>Foo</H1> -const U32 PF_RESTRICT_PUSHOBJECT = 1 << 21; // Restrict push object to either on agent or on scripts owned by parcel owner -const U32 PF_DENY_ANONYMOUS = 1 << 22; // Deny all non identified/transacted accounts -// const U32 PF_DENY_IDENTIFIED = 1 << 23; // Deny identified accounts -// const U32 PF_DENY_TRANSACTED = 1 << 24; // Deny identified accounts -const U32 PF_ALLOW_GROUP_SCRIPTS = 1 << 25; // Allow scripts owned by group -const U32 PF_CREATE_GROUP_OBJECTS = 1 << 26; // Allow object creation by group members or objects -const U32 PF_ALLOW_ALL_OBJECT_ENTRY = 1 << 27; // Allow all objects to enter a parcel -const U32 PF_ALLOW_GROUP_OBJECT_ENTRY = 1 << 28; // Only allow group (and owner) objects to enter the parcel -const U32 PF_ALLOW_VOICE_CHAT = 1 << 29; // Allow residents to use voice chat on this parcel +const U32 PF_USE_ACCESS_GROUP = 1 << 8; +const U32 PF_USE_ACCESS_LIST = 1 << 9; +const U32 PF_USE_BAN_LIST = 1 << 10; +const U32 PF_USE_PASS_LIST = 1 << 11; +const U32 PF_SHOW_DIRECTORY = 1 << 12; +const U32 PF_ALLOW_DEED_TO_GROUP = 1 << 13; +const U32 PF_CONTRIBUTE_WITH_DEED = 1 << 14; +const U32 PF_SOUND_LOCAL = 1 << 15; // Hear sounds in this parcel only +const U32 PF_SELL_PARCEL_OBJECTS = 1 << 16; // Objects on land are included as part of the land when the land is sold +const U32 PF_ALLOW_PUBLISH = 1 << 17; // Allow publishing of parcel information on the web +const U32 PF_MATURE_PUBLISH = 1 << 18; // The information on this parcel is mature +const U32 PF_URL_WEB_PAGE = 1 << 19; // The "media URL" is an HTML page +const U32 PF_URL_RAW_HTML = 1 << 20; // The "media URL" is a raw HTML string like <H1>Foo</H1> +const U32 PF_RESTRICT_PUSHOBJECT = 1 << 21; // Restrict push object to either on agent or on scripts owned by parcel owner +const U32 PF_DENY_ANONYMOUS = 1 << 22; // Deny all non identified/transacted accounts +// const U32 PF_DENY_IDENTIFIED = 1 << 23; // Deny identified accounts +// const U32 PF_DENY_TRANSACTED = 1 << 24; // Deny identified accounts +const U32 PF_ALLOW_GROUP_SCRIPTS = 1 << 25; // Allow scripts owned by group +const U32 PF_CREATE_GROUP_OBJECTS = 1 << 26; // Allow object creation by group members or objects +const U32 PF_ALLOW_ALL_OBJECT_ENTRY = 1 << 27; // Allow all objects to enter a parcel +const U32 PF_ALLOW_GROUP_OBJECT_ENTRY = 1 << 28; // Only allow group (and owner) objects to enter the parcel +const U32 PF_ALLOW_VOICE_CHAT = 1 << 29; // Allow residents to use voice chat on this parcel const U32 PF_USE_ESTATE_VOICE_CHAN = 1 << 30; -const U32 PF_DENY_AGEUNVERIFIED = 1 << 31; // Prevent residents who aren't age-verified +const U32 PF_DENY_AGEUNVERIFIED = 1 << 31; // Prevent residents who aren't age-verified // NOTE: At one point we have used all of the bits. // We have deprecated two of them in 1.19.0 which *could* be reused, // but only after we are certain there are no simstates using those bits. -//const U32 PF_RESERVED = 1U << 31; +//const U32 PF_RESERVED = 1U << 31; // If any of these are true the parcel is restricting access in some maner. const U32 PF_USE_RESTRICTED_ACCESS = PF_USE_ACCESS_GROUP - | PF_USE_ACCESS_LIST - | PF_USE_BAN_LIST - | PF_USE_PASS_LIST - | PF_DENY_ANONYMOUS - | PF_DENY_AGEUNVERIFIED; + | PF_USE_ACCESS_LIST + | PF_USE_BAN_LIST + | PF_USE_PASS_LIST + | PF_DENY_ANONYMOUS + | PF_DENY_AGEUNVERIFIED; const U32 PF_NONE = 0x00000000; const U32 PF_ALL = 0xFFFFFFFF; const U32 PF_DEFAULT = PF_ALLOW_FLY - | PF_ALLOW_OTHER_SCRIPTS - | PF_ALLOW_GROUP_SCRIPTS - | PF_ALLOW_LANDMARK - | PF_CREATE_OBJECTS - | PF_CREATE_GROUP_OBJECTS - | PF_USE_BAN_LIST - | PF_ALLOW_ALL_OBJECT_ENTRY - | PF_ALLOW_GROUP_OBJECT_ENTRY + | PF_ALLOW_OTHER_SCRIPTS + | PF_ALLOW_GROUP_SCRIPTS + | PF_ALLOW_LANDMARK + | PF_CREATE_OBJECTS + | PF_CREATE_GROUP_OBJECTS + | PF_USE_BAN_LIST + | PF_ALLOW_ALL_OBJECT_ENTRY + | PF_ALLOW_GROUP_OBJECT_ENTRY | PF_ALLOW_VOICE_CHAT | PF_USE_ESTATE_VOICE_CHAN; // Access list flags -const U32 AL_ACCESS = (1 << 0); -const U32 AL_BAN = (1 << 1); -const U32 AL_ALLOW_EXPERIENCE = (1 << 3); -const U32 AL_BLOCK_EXPERIENCE = (1 << 4); +const U32 AL_ACCESS = (1 << 0); +const U32 AL_BAN = (1 << 1); +const U32 AL_ALLOW_EXPERIENCE = (1 << 3); +const U32 AL_BLOCK_EXPERIENCE = (1 << 4); //const U32 AL_RENTER = (1 << 2); // Block access return values. BA_ALLOWED is the only success case @@ -107,20 +107,20 @@ const S32 BA_NO_ACCESS_LEVEL = 4; const S32 BA_NOT_AGE_VERIFIED = 5; // ParcelRelease flags -const U32 PR_NONE = 0x0; -const U32 PR_GOD_FORCE = (1 << 0); +const U32 PR_NONE = 0x0; +const U32 PR_GOD_FORCE = (1 << 0); enum EObjectCategory { - OC_INVALID = -1, - OC_NONE = 0, - OC_TOTAL = 0, // yes zero, like OC_NONE - OC_OWNER, - OC_GROUP, - OC_OTHER, - OC_SELECTED, - OC_TEMP, - OC_COUNT + OC_INVALID = -1, + OC_NONE = 0, + OC_TOTAL = 0, // yes zero, like OC_NONE + OC_OWNER, + OC_GROUP, + OC_OTHER, + OC_SELECTED, + OC_TEMP, + OC_COUNT }; const S32 PARCEL_DETAILS_NAME = 0; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index b119a549f5..4bac324527 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -1,1052 +1,1052 @@ -/** - * @file llpermissions.cpp - * @author Phoenix - * @brief Permissions for objects and inventory. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llpermissions.h" - -// library includes -#include "message.h" -#include "llsd.h" - -///---------------------------------------------------------------------------- -/// Class LLPermissions -///---------------------------------------------------------------------------- - -const LLPermissions LLPermissions::DEFAULT; - -// No creator = created by system -LLPermissions::LLPermissions() -{ - init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); -} - - -// Default to created by system -void LLPermissions::init(const LLUUID& creator, const LLUUID& owner, const LLUUID& last_owner, const LLUUID& group) -{ - mCreator = creator; - mOwner = owner; - mLastOwner = last_owner; - mGroup = group; - - mMaskBase = PERM_ALL; - mMaskOwner = PERM_ALL; - mMaskEveryone = PERM_ALL; - mMaskGroup = PERM_ALL; - mMaskNextOwner = PERM_ALL; - fixOwnership(); -} - - -void LLPermissions::initMasks(PermissionMask base, PermissionMask owner, - PermissionMask everyone, PermissionMask group, - PermissionMask next) -{ - mMaskBase = base; - mMaskOwner = owner; - mMaskEveryone = everyone; - mMaskGroup = group; - mMaskNextOwner = next; - fixFairUse(); - fix(); -} - -// ! BACKWARDS COMPATIBILITY ! Override masks for inventory types that -// no longer can have restricted permissions. This takes care of previous -// version landmarks that could have had no copy/mod/transfer bits set. -void LLPermissions::initMasks(LLInventoryType::EType type) -{ - if (LLInventoryType::cannotRestrictPermissions(type)) - { - initMasks(PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL); - } -} - -bool LLPermissions::getOwnership(LLUUID& owner_id, bool& is_group_owned) const -{ - if(mOwner.notNull()) - { - owner_id = mOwner; - is_group_owned = false; - return true; - } - else if(mIsGroupOwned) - { - owner_id = mGroup; - is_group_owned = true; - return true; - } - return false; -} - -LLUUID LLPermissions::getSafeOwner() const -{ - if(mOwner.notNull()) - { - return mOwner; - } - else if(mIsGroupOwned) - { - return mGroup; - } - else - { - LL_WARNS() << "LLPermissions::getSafeOwner() called with no valid owner!" << LL_ENDL; - LLUUID unused_uuid; - unused_uuid.generate(); - - return unused_uuid; - } -} - -U32 LLPermissions::getCRC32() const -{ - U32 rv = mCreator.getCRC32(); - rv += mOwner.getCRC32(); - rv += mLastOwner.getCRC32(); - rv += mGroup.getCRC32(); - rv += mMaskBase + mMaskOwner + mMaskEveryone + mMaskGroup; - return rv; -} - -void LLPermissions::set(const LLPermissions& from) -{ - mCreator = from.mCreator; - mOwner = from.mOwner; - mLastOwner = from.mLastOwner; - mGroup = from.mGroup; - - mMaskBase = from.mMaskBase; - mMaskOwner = from.mMaskOwner; - mMaskEveryone = from.mMaskEveryone; - mMaskGroup = from.mMaskGroup; - mMaskNextOwner = from.mMaskNextOwner; - mIsGroupOwned = from.mIsGroupOwned; -} - -// Fix hierarchy of permissions. -void LLPermissions::fix() -{ - mMaskOwner &= mMaskBase; - mMaskGroup &= mMaskOwner; - // next owner uses base, since you may want to sell locked objects. - mMaskNextOwner &= mMaskBase; - mMaskEveryone &= mMaskOwner; - mMaskEveryone &= ~PERM_MODIFY; - if(!(mMaskBase & PERM_TRANSFER) && !mIsGroupOwned) - { - mMaskGroup &= ~PERM_COPY; - mMaskEveryone &= ~PERM_COPY; - // Do not set mask next owner to too restrictive because if we - // rez an object, it may require an ownership transfer during - // rez, which will note the overly restrictive perms, and then - // fix them to allow fair use, which may be different than the - // original intention. - } -} - -// Correct for fair use - you can never take away the right to move -// stuff you own, and you can never take away the right to transfer -// something you cannot otherwise copy. -void LLPermissions::fixFairUse() -{ - mMaskBase |= PERM_MOVE; - if(!(mMaskBase & PERM_COPY)) - { - mMaskBase |= PERM_TRANSFER; - } - // (mask next owner == PERM_NONE) iff mask base is no transfer - if(mMaskNextOwner != PERM_NONE) - { - mMaskNextOwner |= PERM_MOVE; - } -} - -void LLPermissions::fixOwnership() -{ - if(mOwner.isNull() && mGroup.notNull()) - { - mIsGroupOwned = true; - } - else - { - mIsGroupOwned = false; - } -} - -// Allow accumulation of permissions. Results in the tightest -// permissions possible. In the case of clashing UUIDs, it sets the ID -// to LLUUID::null. -void LLPermissions::accumulate(const LLPermissions& perm) -{ - if(perm.mCreator != mCreator) - { - mCreator = LLUUID::null; - } - if(perm.mOwner != mOwner) - { - mOwner = LLUUID::null; - } - if(perm.mLastOwner != mLastOwner) - { - mLastOwner = LLUUID::null; - } - if(perm.mGroup != mGroup) - { - mGroup = LLUUID::null; - } - - mMaskBase &= perm.mMaskBase; - mMaskOwner &= perm.mMaskOwner; - mMaskGroup &= perm.mMaskGroup; - mMaskEveryone &= perm.mMaskEveryone; - mMaskNextOwner &= perm.mMaskNextOwner; - fix(); -} - -// saves last owner, sets current owner, and sets the group. note -// that this function has to more cleverly apply the fair use -// permissions. -bool LLPermissions::setOwnerAndGroup( - const LLUUID& agent, - const LLUUID& owner, - const LLUUID& group, - bool is_atomic) -{ - bool allowed = false; - - if( agent.isNull() || mOwner.isNull() - || ((agent == mOwner) && ((owner == mOwner) || (mMaskOwner & PERM_TRANSFER)) ) ) - { - // ...system can alway set owner - // ...public objects can be claimed by anyone - // ...otherwise, agent must own it and have transfer ability - allowed = true; - } - - if (allowed) - { - if(mLastOwner.isNull() || (!mOwner.isNull() && (owner != mLastOwner))) - { - mLastOwner = mOwner; - } - if((mOwner != owner) - || (mOwner.isNull() && owner.isNull() && (mGroup != group))) - { - mMaskBase = mMaskNextOwner; - mOwner = owner; - // this is a selective use of fair use for atomic - // permissions. - if(is_atomic && !(mMaskBase & PERM_COPY)) - { - mMaskBase |= PERM_TRANSFER; - } - } - mGroup = group; - fixOwnership(); - // if it's not atomic and we fix fair use, it blows away - //objects as inventory items which have different permissions - //than it's contents. :( - // fixFairUse(); - mMaskBase |= PERM_MOVE; - if(mMaskNextOwner != PERM_NONE) mMaskNextOwner |= PERM_MOVE; - fix(); - } - - return allowed; -} - -//Fix for DEV-33917, last owner isn't used much and has little impact on -//permissions so it's reasonably safe to do this, however, for now, -//limiting the functionality of this routine to objects which are -//group owned. -void LLPermissions::setLastOwner(const LLUUID& last_owner) -{ - if (isGroupOwned()) - mLastOwner = last_owner; -} - - -// only call this if you know what you're doing -// there are usually perm-bit consequences when the -// ownerhsip changes -void LLPermissions::yesReallySetOwner(const LLUUID& owner, bool group_owned) -{ - mOwner = owner; - mIsGroupOwned = group_owned; -} - -bool LLPermissions::deedToGroup(const LLUUID& agent, const LLUUID& group) -{ - if(group.notNull() && (agent.isNull() || ((group == mGroup) - && (mMaskOwner & PERM_TRANSFER) - && (mMaskGroup & PERM_MOVE)))) - { - if(mOwner.notNull()) - { - mLastOwner = mOwner; - mOwner.setNull(); - } - mMaskBase = mMaskNextOwner; - mMaskGroup = PERM_NONE; - mGroup = group; - mIsGroupOwned = true; - fixFairUse(); - fix(); - return true; - } - return false; -} - -bool LLPermissions::setBaseBits(const LLUUID& agent, bool set, PermissionMask bits) -{ - bool ownership = false; - if(agent.isNull()) - { - // only the system is always allowed to change base bits - ownership = true; - } - - if (ownership) - { - if (set) - { - mMaskBase |= bits; // turn on bits - } - else - { - mMaskBase &= ~bits; // turn off bits - } - fix(); - } - - return ownership; -} - - -// Note: If you attempt to set bits that the base bits doesn't allow, -// the function will succeed, but those bits will not be set. -bool LLPermissions::setOwnerBits(const LLUUID& agent, bool set, PermissionMask bits) -{ - bool ownership = false; - - if(agent.isNull()) - { - // ...system always allowed to change things - ownership = true; - } - else if (agent == mOwner) - { - // ...owner bits can only be set by owner - ownership = true; - } - - // If we have correct ownership and - if (ownership) - { - if (set) - { - mMaskOwner |= bits; // turn on bits - } - else - { - mMaskOwner &= ~bits; // turn off bits - } - fix(); - } - - return (ownership); -} - -bool LLPermissions::setGroupBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits) -{ - bool ownership = false; - if((agent.isNull()) || (agent == mOwner) - || ((group == mGroup) && (!mGroup.isNull()))) - { - // The group bits can be set by the system, the owner, or a - // group member. - ownership = true; - } - - if (ownership) - { - if (set) - { - mMaskGroup |= bits; - } - else - { - mMaskGroup &= ~bits; - } - fix(); - } - return ownership; -} - - -// Note: If you attempt to set bits that the creator or owner doesn't allow, -// the function will succeed, but those bits will not be set. -bool LLPermissions::setEveryoneBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits) -{ - bool ownership = false; - if((agent.isNull()) || (agent == mOwner) - || ((group == mGroup) && (!mGroup.isNull()))) - { - // The everyone bits can be set by the system, the owner, or a - // group member. - ownership = true; - } - if (ownership) - { - if (set) - { - mMaskEveryone |= bits; - } - else - { - mMaskEveryone &= ~bits; - } - - // Fix hierarchy of permissions - fix(); - } - return ownership; -} - -// Note: If you attempt to set bits that the creator or owner doesn't allow, -// the function will succeed, but those bits will not be set. -bool LLPermissions::setNextOwnerBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits) -{ - bool ownership = false; - if((agent.isNull()) || (agent == mOwner) - || ((group == mGroup) && (!mGroup.isNull()))) - { - // The next owner bits can be set by the system, the owner, or - // a group member. - ownership = true; - } - if (ownership) - { - if (set) - { - mMaskNextOwner |= bits; - } - else - { - mMaskNextOwner &= ~bits; - } - - // Fix-up permissions - if(!(mMaskNextOwner & PERM_COPY)) - { - mMaskNextOwner |= PERM_TRANSFER; - } - fix(); - } - return ownership; -} - -bool LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, const LLUUID& group) const -{ - if(requester.isNull()) - { - // ...system making request - // ...not owned - return true; - } - else if (mIsGroupOwned && (mGroup == requester)) - { - // group checking ownership permissions - return (mMaskOwner & op); - } - else if (!mIsGroupOwned && (mOwner == requester)) - { - // ...owner making request - return (mMaskOwner & op); - } - else if(mGroup.notNull() && (mGroup == group)) - { - // group member making request - return ((mMaskGroup & op) || (mMaskEveryone & op)); - } - return (mMaskEveryone & op); -} - -// -// LLSD support for HTTP messages. -// -LLSD LLPermissions::packMessage() const -{ - LLSD result; - result["creator-id"] = mCreator; - result["owner-id"] = mOwner; - result["group-id"] = mGroup; - - result["base-mask"] = (S32)mMaskBase; - result["owner-mask"] = (S32)mMaskOwner; - result["group-mask"] = (S32)mMaskGroup; - result["everyone-mask"] = (S32)mMaskEveryone; - result["next-owner-mask"]= (S32)mMaskNextOwner; - result["group-owned"] = (bool)mIsGroupOwned; - return result; -} - -// -// Messaging support -// -void LLPermissions::packMessage(LLMessageSystem* msg) const -{ - msg->addUUIDFast(_PREHASH_CreatorID, mCreator); - msg->addUUIDFast(_PREHASH_OwnerID, mOwner); - msg->addUUIDFast(_PREHASH_GroupID, mGroup); - - msg->addU32Fast(_PREHASH_BaseMask, mMaskBase ); - msg->addU32Fast(_PREHASH_OwnerMask, mMaskOwner ); - msg->addU32Fast(_PREHASH_GroupMask, mMaskGroup ); - msg->addU32Fast(_PREHASH_EveryoneMask, mMaskEveryone ); - msg->addU32Fast(_PREHASH_NextOwnerMask, mMaskNextOwner ); - msg->addBOOLFast(_PREHASH_GroupOwned, mIsGroupOwned); -} - -void LLPermissions::unpackMessage(LLSD perms) -{ - mCreator = perms["creator-id"]; - mOwner = perms["owner-id"]; - mGroup = perms["group-id"]; - - mMaskBase = (U32)perms["base-mask"].asInteger(); - mMaskOwner = (U32)perms["owner-mask"].asInteger(); - mMaskGroup = (U32)perms["group-mask"].asInteger(); - mMaskEveryone = (U32)perms["everyone-mask"].asInteger(); - mMaskNextOwner = (U32)perms["next-owner-mask"].asInteger(); - mIsGroupOwned = perms["group-owned"].asBoolean(); -} - -void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num) -{ - msg->getUUIDFast(block, _PREHASH_CreatorID, mCreator, block_num); - msg->getUUIDFast(block, _PREHASH_OwnerID, mOwner, block_num); - msg->getUUIDFast(block, _PREHASH_GroupID, mGroup, block_num); - - msg->getU32Fast(block, _PREHASH_BaseMask, mMaskBase, block_num ); - msg->getU32Fast(block, _PREHASH_OwnerMask, mMaskOwner, block_num ); - msg->getU32Fast(block, _PREHASH_GroupMask, mMaskGroup, block_num ); - msg->getU32Fast(block, _PREHASH_EveryoneMask, mMaskEveryone, block_num ); - msg->getU32Fast(block, _PREHASH_NextOwnerMask, mMaskNextOwner, block_num ); - bool tmp; - msg->getBOOLFast(block, _PREHASH_GroupOwned, tmp, block_num); - mIsGroupOwned = tmp; -} - - -bool LLPermissions::importLegacyStream(std::istream& input_stream) -{ - init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); - const S32 BUFSIZE = 16384; - - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[BUFSIZE]; /* Flawfinder: ignore */ - char keyword[256]; /* Flawfinder: ignore */ - char valuestr[256]; /* Flawfinder: ignore */ - char uuid_str[256]; /* Flawfinder: ignore */ - U32 mask; - - keyword[0] = '\0'; - valuestr[0] = '\0'; - - while (input_stream.good()) - { - input_stream.getline(buffer, BUFSIZE); - sscanf( /* Flawfinder: ignore */ - buffer, - " %255s %255s", - keyword, valuestr); - if (!strcmp("{", keyword)) - { - continue; - } - if (!strcmp("}",keyword)) - { - break; - } - else if (!strcmp("creator_mask", keyword)) - { - // legacy support for "creator" masks - sscanf(valuestr, "%x", &mask); - mMaskBase = mask; - fixFairUse(); - } - else if (!strcmp("base_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskBase = mask; - //fixFairUse(); - } - else if (!strcmp("owner_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskOwner = mask; - } - else if (!strcmp("group_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskGroup = mask; - } - else if (!strcmp("everyone_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskEveryone = mask; - } - else if (!strcmp("next_owner_mask", keyword)) - { - sscanf(valuestr, "%x", &mask); - mMaskNextOwner = mask; - } - else if (!strcmp("creator_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mCreator.set(uuid_str); - } - else if (!strcmp("owner_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mOwner.set(uuid_str); - } - else if (!strcmp("last_owner_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mLastOwner.set(uuid_str); - } - else if (!strcmp("group_id", keyword)) - { - sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */ - mGroup.set(uuid_str); - } - else if (!strcmp("group_owned", keyword)) - { - sscanf(valuestr, "%d", &mask); - if(mask) mIsGroupOwned = true; - else mIsGroupOwned = false; - } - else - { - LL_INFOS() << "unknown keyword " << keyword << " in permissions import" << LL_ENDL; - } - } - fix(); - return true; -} - - -bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const -{ - std::string uuid_str; - - output_stream << "\tpermissions 0\n"; - output_stream << "\t{\n"; - - std::string buffer; - buffer = llformat( "\t\tbase_mask\t%08x\n", mMaskBase); - output_stream << buffer; - buffer = llformat( "\t\towner_mask\t%08x\n", mMaskOwner); - output_stream << buffer; - buffer = llformat( "\t\tgroup_mask\t%08x\n", mMaskGroup); - output_stream << buffer; - buffer = llformat( "\t\teveryone_mask\t%08x\n", mMaskEveryone); - output_stream << buffer; - buffer = llformat( "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner); - output_stream << buffer; - - mCreator.toString(uuid_str); - output_stream << "\t\tcreator_id\t" << uuid_str << "\n"; - - mOwner.toString(uuid_str); - output_stream << "\t\towner_id\t" << uuid_str << "\n"; - - mLastOwner.toString(uuid_str); - output_stream << "\t\tlast_owner_id\t" << uuid_str << "\n"; - - mGroup.toString(uuid_str); - output_stream << "\t\tgroup_id\t" << uuid_str << "\n"; - - if(mIsGroupOwned) - { - output_stream << "\t\tgroup_owned\t1\n"; - } - output_stream << "\t}\n"; - return true; -} - -bool LLPermissions::operator==(const LLPermissions &rhs) const -{ - return - (mCreator == rhs.mCreator) && - (mOwner == rhs.mOwner) && - (mLastOwner == rhs.mLastOwner ) && - (mGroup == rhs.mGroup ) && - (mMaskBase == rhs.mMaskBase ) && - (mMaskOwner == rhs.mMaskOwner ) && - (mMaskGroup == rhs.mMaskGroup ) && - (mMaskEveryone == rhs.mMaskEveryone ) && - (mMaskNextOwner == rhs.mMaskNextOwner ) && - (mIsGroupOwned == rhs.mIsGroupOwned); -} - - -bool LLPermissions::operator!=(const LLPermissions &rhs) const -{ - return - (mCreator != rhs.mCreator) || - (mOwner != rhs.mOwner) || - (mLastOwner != rhs.mLastOwner ) || - (mGroup != rhs.mGroup ) || - (mMaskBase != rhs.mMaskBase ) || - (mMaskOwner != rhs.mMaskOwner ) || - (mMaskGroup != rhs.mMaskGroup ) || - (mMaskEveryone != rhs.mMaskEveryone ) || - (mMaskNextOwner != rhs.mMaskNextOwner) || - (mIsGroupOwned != rhs.mIsGroupOwned); -} - -std::ostream& operator<<(std::ostream &s, const LLPermissions &perm) -{ - s << "{Creator=" << perm.getCreator(); - s << ", Owner=" << perm.getOwner(); - s << ", Group=" << perm.getGroup(); - s << std::hex << ", BaseMask=0x" << perm.getMaskBase(); - s << ", OwnerMask=0x" << perm.getMaskOwner(); - s << ", EveryoneMask=0x" << perm.getMaskEveryone(); - s << ", GroupMask=0x" << perm.getMaskGroup(); - s << ", NextOwnerMask=0x" << perm.getMaskNextOwner() << std::dec; - s << "}"; - return s; -} - -///---------------------------------------------------------------------------- -/// Class LLAggregatePermissions -///---------------------------------------------------------------------------- - -const LLAggregatePermissions LLAggregatePermissions::empty; - - -LLAggregatePermissions::LLAggregatePermissions() -{ - for(S32 i = 0; i < PI_COUNT; ++i) - { - mBits[i] = AP_EMPTY; - } -} - -LLAggregatePermissions::EValue LLAggregatePermissions::getValue(PermissionBit bit) const -{ - EPermIndex idx = perm2PermIndex(bit); - EValue rv = AP_EMPTY; - if(idx != PI_END) - { - rv = (LLAggregatePermissions::EValue)(mBits[idx]); - } - return rv; -} - -// returns the bits compressed into a single byte: 00TTMMCC -// where TT = transfer, MM = modify, and CC = copy -// LSB is to the right -U8 LLAggregatePermissions::getU8() const -{ - U8 byte = mBits[PI_TRANSFER]; - byte <<= 2; - byte |= mBits[PI_MODIFY]; - byte <<= 2; - byte |= mBits[PI_COPY]; - return byte; -} - -bool LLAggregatePermissions::isEmpty() const -{ - for(S32 i = 0; i < PI_END; ++i) - { - if(mBits[i] != AP_EMPTY) - { - return false; - } - } - return true; -} - -void LLAggregatePermissions::aggregate(PermissionMask mask) -{ - bool is_allowed = mask & PERM_COPY; - aggregateBit(PI_COPY, is_allowed); - is_allowed = mask & PERM_MODIFY; - aggregateBit(PI_MODIFY, is_allowed); - is_allowed = mask & PERM_TRANSFER; - aggregateBit(PI_TRANSFER, is_allowed); -} - -void LLAggregatePermissions::aggregate(const LLAggregatePermissions& ag) -{ - for(S32 idx = PI_COPY; idx != PI_END; ++idx) - { - aggregateIndex((EPermIndex)idx, ag.mBits[idx]); - } -} - -void LLAggregatePermissions::aggregateBit(EPermIndex idx, bool allowed) -{ - //if(AP_SOME == mBits[idx]) return; // P4 branch prediction optimization - switch(mBits[idx]) - { - case AP_EMPTY: - mBits[idx] = allowed ? AP_ALL : AP_NONE; - break; - case AP_NONE: - mBits[idx] = allowed ? AP_SOME: AP_NONE; - break; - case AP_SOME: - // no-op - break; - case AP_ALL: - mBits[idx] = allowed ? AP_ALL : AP_SOME; - break; - default: - LL_WARNS() << "Bad aggregateBit " << (S32)idx << " " - << (allowed ? "true" : "false") << LL_ENDL; - break; - } -} - -void LLAggregatePermissions::aggregateIndex(EPermIndex idx, U8 bits) -{ - switch(mBits[idx]) - { - case AP_EMPTY: - mBits[idx] = bits; - break; - case AP_NONE: - switch(bits) - { - case AP_SOME: - case AP_ALL: - mBits[idx] = AP_SOME; - break; - case AP_EMPTY: - case AP_NONE: - default: - // no-op - break; - } - break; - case AP_SOME: - // no-op - break; - case AP_ALL: - switch(bits) - { - case AP_NONE: - case AP_SOME: - mBits[idx] = AP_SOME; - break; - case AP_EMPTY: - case AP_ALL: - default: - // no-op - break; - } - break; - default: - LL_WARNS() << "Bad aggregate index " << (S32)idx << " " - << (S32)bits << LL_ENDL; - break; - } -} - -// static -LLAggregatePermissions::EPermIndex LLAggregatePermissions::perm2PermIndex(PermissionBit bit) -{ - EPermIndex idx = PI_END; // past any good value. - switch(bit) - { - case PERM_COPY: - idx = PI_COPY; - break; - case PERM_MODIFY: - idx = PI_MODIFY; - break; - case PERM_TRANSFER: - idx = PI_TRANSFER; - break; - default: - break; - } - return idx; -} - - -void LLAggregatePermissions::packMessage(LLMessageSystem* msg, const char* field) const -{ - msg->addU8Fast(field, getU8()); -} - -void LLAggregatePermissions::unpackMessage(LLMessageSystem* msg, const char* block, const char* field, S32 block_num) -{ - const U8 TWO_BITS = 0x3; // binary 00000011 - U8 bits = 0; - msg->getU8Fast(block, field, bits, block_num); - mBits[PI_COPY] = bits & TWO_BITS; - bits >>= 2; - mBits[PI_MODIFY] = bits & TWO_BITS; - bits >>= 2; - mBits[PI_TRANSFER] = bits & TWO_BITS; -} - -const std::string AGGREGATE_VALUES[4] = - { - std::string( "Empty" ), - std::string( "None" ), - std::string( "Some" ), - std::string( "All" ) - }; - -std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm) -{ - s << "{PI_COPY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_COPY]]; - s << ", PI_MODIFY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_MODIFY]]; - s << ", PI_TRANSFER=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_TRANSFER]]; - s << "}"; - return s; -} - -// This converts a permissions mask into a string for debugging use. -void mask_to_string(U32 mask, char* str) -{ - if (mask & PERM_MOVE) - { - *str = 'V'; - } - else - { - *str = ' '; - } - str++; - - if (mask & PERM_MODIFY) - { - *str = 'M'; - } - else - { - *str = ' '; - } - str++; - - if (mask & PERM_COPY) - { - *str = 'C'; - } - else - { - *str = ' '; - } - str++; - - if (mask & PERM_TRANSFER) - { - *str = 'T'; - } - else - { - *str = ' '; - } - str++; - *str = '\0'; -} - -std::string mask_to_string(U32 mask) -{ - char str[16]; - mask_to_string(mask, str); - return std::string(str); -} - -///---------------------------------------------------------------------------- -/// exported functions -///---------------------------------------------------------------------------- -static const std::string PERM_CREATOR_ID_LABEL("creator_id"); -static const std::string PERM_OWNER_ID_LABEL("owner_id"); -static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id"); -static const std::string PERM_GROUP_ID_LABEL("group_id"); -static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group"); -static const std::string PERM_BASE_MASK_LABEL("base_mask"); -static const std::string PERM_OWNER_MASK_LABEL("owner_mask"); -static const std::string PERM_GROUP_MASK_LABEL("group_mask"); -static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask"); -static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask"); - -LLSD ll_create_sd_from_permissions(const LLPermissions& perm) -{ - LLSD rv; - rv[PERM_CREATOR_ID_LABEL] = perm.getCreator(); - rv[PERM_OWNER_ID_LABEL] = perm.getOwner(); - rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner(); - rv[PERM_GROUP_ID_LABEL] = perm.getGroup(); - rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned(); - rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase(); - rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner(); - rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup(); - rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone(); - rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner(); - return rv; -} - -LLPermissions ll_permissions_from_sd(const LLSD& sd_perm) -{ - LLPermissions rv; - rv.init( - sd_perm[PERM_CREATOR_ID_LABEL].asUUID(), - sd_perm[PERM_OWNER_ID_LABEL].asUUID(), - sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(), - sd_perm[PERM_GROUP_ID_LABEL].asUUID()); - - // We do a cast to U32 here since LLSD does not attempt to - // represent unsigned ints. - PermissionMask mask; - mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger()); - rv.setMaskBase(mask); - mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger()); - rv.setMaskOwner(mask); - mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger()); - rv.setMaskEveryone(mask); - mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger()); - rv.setMaskGroup(mask); - mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger()); - rv.setMaskNext(mask); - rv.fix(); - return rv; -} +/**
+ * @file llpermissions.cpp
+ * @author Phoenix
+ * @brief Permissions for objects and inventory.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpermissions.h"
+
+// library includes
+#include "message.h"
+#include "llsd.h"
+
+///----------------------------------------------------------------------------
+/// Class LLPermissions
+///----------------------------------------------------------------------------
+
+const LLPermissions LLPermissions::DEFAULT;
+
+// No creator = created by system
+LLPermissions::LLPermissions()
+{
+ init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
+}
+
+
+// Default to created by system
+void LLPermissions::init(const LLUUID& creator, const LLUUID& owner, const LLUUID& last_owner, const LLUUID& group)
+{
+ mCreator = creator;
+ mOwner = owner;
+ mLastOwner = last_owner;
+ mGroup = group;
+
+ mMaskBase = PERM_ALL;
+ mMaskOwner = PERM_ALL;
+ mMaskEveryone = PERM_ALL;
+ mMaskGroup = PERM_ALL;
+ mMaskNextOwner = PERM_ALL;
+ fixOwnership();
+}
+
+
+void LLPermissions::initMasks(PermissionMask base, PermissionMask owner,
+ PermissionMask everyone, PermissionMask group,
+ PermissionMask next)
+{
+ mMaskBase = base;
+ mMaskOwner = owner;
+ mMaskEveryone = everyone;
+ mMaskGroup = group;
+ mMaskNextOwner = next;
+ fixFairUse();
+ fix();
+}
+
+// ! BACKWARDS COMPATIBILITY ! Override masks for inventory types that
+// no longer can have restricted permissions. This takes care of previous
+// version landmarks that could have had no copy/mod/transfer bits set.
+void LLPermissions::initMasks(LLInventoryType::EType type)
+{
+ if (LLInventoryType::cannotRestrictPermissions(type))
+ {
+ initMasks(PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL);
+ }
+}
+
+bool LLPermissions::getOwnership(LLUUID& owner_id, bool& is_group_owned) const
+{
+ if(mOwner.notNull())
+ {
+ owner_id = mOwner;
+ is_group_owned = false;
+ return true;
+ }
+ else if(mIsGroupOwned)
+ {
+ owner_id = mGroup;
+ is_group_owned = true;
+ return true;
+ }
+ return false;
+}
+
+LLUUID LLPermissions::getSafeOwner() const
+{
+ if(mOwner.notNull())
+ {
+ return mOwner;
+ }
+ else if(mIsGroupOwned)
+ {
+ return mGroup;
+ }
+ else
+ {
+ LL_WARNS() << "LLPermissions::getSafeOwner() called with no valid owner!" << LL_ENDL;
+ LLUUID unused_uuid;
+ unused_uuid.generate();
+
+ return unused_uuid;
+ }
+}
+
+U32 LLPermissions::getCRC32() const
+{
+ U32 rv = mCreator.getCRC32();
+ rv += mOwner.getCRC32();
+ rv += mLastOwner.getCRC32();
+ rv += mGroup.getCRC32();
+ rv += mMaskBase + mMaskOwner + mMaskEveryone + mMaskGroup;
+ return rv;
+}
+
+void LLPermissions::set(const LLPermissions& from)
+{
+ mCreator = from.mCreator;
+ mOwner = from.mOwner;
+ mLastOwner = from.mLastOwner;
+ mGroup = from.mGroup;
+
+ mMaskBase = from.mMaskBase;
+ mMaskOwner = from.mMaskOwner;
+ mMaskEveryone = from.mMaskEveryone;
+ mMaskGroup = from.mMaskGroup;
+ mMaskNextOwner = from.mMaskNextOwner;
+ mIsGroupOwned = from.mIsGroupOwned;
+}
+
+// Fix hierarchy of permissions.
+void LLPermissions::fix()
+{
+ mMaskOwner &= mMaskBase;
+ mMaskGroup &= mMaskOwner;
+ // next owner uses base, since you may want to sell locked objects.
+ mMaskNextOwner &= mMaskBase;
+ mMaskEveryone &= mMaskOwner;
+ mMaskEveryone &= ~PERM_MODIFY;
+ if(!(mMaskBase & PERM_TRANSFER) && !mIsGroupOwned)
+ {
+ mMaskGroup &= ~PERM_COPY;
+ mMaskEveryone &= ~PERM_COPY;
+ // Do not set mask next owner to too restrictive because if we
+ // rez an object, it may require an ownership transfer during
+ // rez, which will note the overly restrictive perms, and then
+ // fix them to allow fair use, which may be different than the
+ // original intention.
+ }
+}
+
+// Correct for fair use - you can never take away the right to move
+// stuff you own, and you can never take away the right to transfer
+// something you cannot otherwise copy.
+void LLPermissions::fixFairUse()
+{
+ mMaskBase |= PERM_MOVE;
+ if(!(mMaskBase & PERM_COPY))
+ {
+ mMaskBase |= PERM_TRANSFER;
+ }
+ // (mask next owner == PERM_NONE) iff mask base is no transfer
+ if(mMaskNextOwner != PERM_NONE)
+ {
+ mMaskNextOwner |= PERM_MOVE;
+ }
+}
+
+void LLPermissions::fixOwnership()
+{
+ if(mOwner.isNull() && mGroup.notNull())
+ {
+ mIsGroupOwned = true;
+ }
+ else
+ {
+ mIsGroupOwned = false;
+ }
+}
+
+// Allow accumulation of permissions. Results in the tightest
+// permissions possible. In the case of clashing UUIDs, it sets the ID
+// to LLUUID::null.
+void LLPermissions::accumulate(const LLPermissions& perm)
+{
+ if(perm.mCreator != mCreator)
+ {
+ mCreator = LLUUID::null;
+ }
+ if(perm.mOwner != mOwner)
+ {
+ mOwner = LLUUID::null;
+ }
+ if(perm.mLastOwner != mLastOwner)
+ {
+ mLastOwner = LLUUID::null;
+ }
+ if(perm.mGroup != mGroup)
+ {
+ mGroup = LLUUID::null;
+ }
+
+ mMaskBase &= perm.mMaskBase;
+ mMaskOwner &= perm.mMaskOwner;
+ mMaskGroup &= perm.mMaskGroup;
+ mMaskEveryone &= perm.mMaskEveryone;
+ mMaskNextOwner &= perm.mMaskNextOwner;
+ fix();
+}
+
+// saves last owner, sets current owner, and sets the group. note
+// that this function has to more cleverly apply the fair use
+// permissions.
+bool LLPermissions::setOwnerAndGroup(
+ const LLUUID& agent,
+ const LLUUID& owner,
+ const LLUUID& group,
+ bool is_atomic)
+{
+ bool allowed = false;
+
+ if( agent.isNull() || mOwner.isNull()
+ || ((agent == mOwner) && ((owner == mOwner) || (mMaskOwner & PERM_TRANSFER)) ) )
+ {
+ // ...system can alway set owner
+ // ...public objects can be claimed by anyone
+ // ...otherwise, agent must own it and have transfer ability
+ allowed = true;
+ }
+
+ if (allowed)
+ {
+ if(mLastOwner.isNull() || (!mOwner.isNull() && (owner != mLastOwner)))
+ {
+ mLastOwner = mOwner;
+ }
+ if((mOwner != owner)
+ || (mOwner.isNull() && owner.isNull() && (mGroup != group)))
+ {
+ mMaskBase = mMaskNextOwner;
+ mOwner = owner;
+ // this is a selective use of fair use for atomic
+ // permissions.
+ if(is_atomic && !(mMaskBase & PERM_COPY))
+ {
+ mMaskBase |= PERM_TRANSFER;
+ }
+ }
+ mGroup = group;
+ fixOwnership();
+ // if it's not atomic and we fix fair use, it blows away
+ //objects as inventory items which have different permissions
+ //than it's contents. :(
+ // fixFairUse();
+ mMaskBase |= PERM_MOVE;
+ if(mMaskNextOwner != PERM_NONE) mMaskNextOwner |= PERM_MOVE;
+ fix();
+ }
+
+ return allowed;
+}
+
+//Fix for DEV-33917, last owner isn't used much and has little impact on
+//permissions so it's reasonably safe to do this, however, for now,
+//limiting the functionality of this routine to objects which are
+//group owned.
+void LLPermissions::setLastOwner(const LLUUID& last_owner)
+{
+ if (isGroupOwned())
+ mLastOwner = last_owner;
+}
+
+
+// only call this if you know what you're doing
+// there are usually perm-bit consequences when the
+// ownerhsip changes
+void LLPermissions::yesReallySetOwner(const LLUUID& owner, bool group_owned)
+{
+ mOwner = owner;
+ mIsGroupOwned = group_owned;
+}
+
+bool LLPermissions::deedToGroup(const LLUUID& agent, const LLUUID& group)
+{
+ if(group.notNull() && (agent.isNull() || ((group == mGroup)
+ && (mMaskOwner & PERM_TRANSFER)
+ && (mMaskGroup & PERM_MOVE))))
+ {
+ if(mOwner.notNull())
+ {
+ mLastOwner = mOwner;
+ mOwner.setNull();
+ }
+ mMaskBase = mMaskNextOwner;
+ mMaskGroup = PERM_NONE;
+ mGroup = group;
+ mIsGroupOwned = true;
+ fixFairUse();
+ fix();
+ return true;
+ }
+ return false;
+}
+
+bool LLPermissions::setBaseBits(const LLUUID& agent, bool set, PermissionMask bits)
+{
+ bool ownership = false;
+ if(agent.isNull())
+ {
+ // only the system is always allowed to change base bits
+ ownership = true;
+ }
+
+ if (ownership)
+ {
+ if (set)
+ {
+ mMaskBase |= bits; // turn on bits
+ }
+ else
+ {
+ mMaskBase &= ~bits; // turn off bits
+ }
+ fix();
+ }
+
+ return ownership;
+}
+
+
+// Note: If you attempt to set bits that the base bits doesn't allow,
+// the function will succeed, but those bits will not be set.
+bool LLPermissions::setOwnerBits(const LLUUID& agent, bool set, PermissionMask bits)
+{
+ bool ownership = false;
+
+ if(agent.isNull())
+ {
+ // ...system always allowed to change things
+ ownership = true;
+ }
+ else if (agent == mOwner)
+ {
+ // ...owner bits can only be set by owner
+ ownership = true;
+ }
+
+ // If we have correct ownership and
+ if (ownership)
+ {
+ if (set)
+ {
+ mMaskOwner |= bits; // turn on bits
+ }
+ else
+ {
+ mMaskOwner &= ~bits; // turn off bits
+ }
+ fix();
+ }
+
+ return (ownership);
+}
+
+bool LLPermissions::setGroupBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits)
+{
+ bool ownership = false;
+ if((agent.isNull()) || (agent == mOwner)
+ || ((group == mGroup) && (!mGroup.isNull())))
+ {
+ // The group bits can be set by the system, the owner, or a
+ // group member.
+ ownership = true;
+ }
+
+ if (ownership)
+ {
+ if (set)
+ {
+ mMaskGroup |= bits;
+ }
+ else
+ {
+ mMaskGroup &= ~bits;
+ }
+ fix();
+ }
+ return ownership;
+}
+
+
+// Note: If you attempt to set bits that the creator or owner doesn't allow,
+// the function will succeed, but those bits will not be set.
+bool LLPermissions::setEveryoneBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits)
+{
+ bool ownership = false;
+ if((agent.isNull()) || (agent == mOwner)
+ || ((group == mGroup) && (!mGroup.isNull())))
+ {
+ // The everyone bits can be set by the system, the owner, or a
+ // group member.
+ ownership = true;
+ }
+ if (ownership)
+ {
+ if (set)
+ {
+ mMaskEveryone |= bits;
+ }
+ else
+ {
+ mMaskEveryone &= ~bits;
+ }
+
+ // Fix hierarchy of permissions
+ fix();
+ }
+ return ownership;
+}
+
+// Note: If you attempt to set bits that the creator or owner doesn't allow,
+// the function will succeed, but those bits will not be set.
+bool LLPermissions::setNextOwnerBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits)
+{
+ bool ownership = false;
+ if((agent.isNull()) || (agent == mOwner)
+ || ((group == mGroup) && (!mGroup.isNull())))
+ {
+ // The next owner bits can be set by the system, the owner, or
+ // a group member.
+ ownership = true;
+ }
+ if (ownership)
+ {
+ if (set)
+ {
+ mMaskNextOwner |= bits;
+ }
+ else
+ {
+ mMaskNextOwner &= ~bits;
+ }
+
+ // Fix-up permissions
+ if(!(mMaskNextOwner & PERM_COPY))
+ {
+ mMaskNextOwner |= PERM_TRANSFER;
+ }
+ fix();
+ }
+ return ownership;
+}
+
+bool LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, const LLUUID& group) const
+{
+ if(requester.isNull())
+ {
+ // ...system making request
+ // ...not owned
+ return true;
+ }
+ else if (mIsGroupOwned && (mGroup == requester))
+ {
+ // group checking ownership permissions
+ return (mMaskOwner & op);
+ }
+ else if (!mIsGroupOwned && (mOwner == requester))
+ {
+ // ...owner making request
+ return (mMaskOwner & op);
+ }
+ else if(mGroup.notNull() && (mGroup == group))
+ {
+ // group member making request
+ return ((mMaskGroup & op) || (mMaskEveryone & op));
+ }
+ return (mMaskEveryone & op);
+}
+
+//
+// LLSD support for HTTP messages.
+//
+LLSD LLPermissions::packMessage() const
+{
+ LLSD result;
+ result["creator-id"] = mCreator;
+ result["owner-id"] = mOwner;
+ result["group-id"] = mGroup;
+
+ result["base-mask"] = (S32)mMaskBase;
+ result["owner-mask"] = (S32)mMaskOwner;
+ result["group-mask"] = (S32)mMaskGroup;
+ result["everyone-mask"] = (S32)mMaskEveryone;
+ result["next-owner-mask"]= (S32)mMaskNextOwner;
+ result["group-owned"] = (bool)mIsGroupOwned;
+ return result;
+}
+
+//
+// Messaging support
+//
+void LLPermissions::packMessage(LLMessageSystem* msg) const
+{
+ msg->addUUIDFast(_PREHASH_CreatorID, mCreator);
+ msg->addUUIDFast(_PREHASH_OwnerID, mOwner);
+ msg->addUUIDFast(_PREHASH_GroupID, mGroup);
+
+ msg->addU32Fast(_PREHASH_BaseMask, mMaskBase );
+ msg->addU32Fast(_PREHASH_OwnerMask, mMaskOwner );
+ msg->addU32Fast(_PREHASH_GroupMask, mMaskGroup );
+ msg->addU32Fast(_PREHASH_EveryoneMask, mMaskEveryone );
+ msg->addU32Fast(_PREHASH_NextOwnerMask, mMaskNextOwner );
+ msg->addBOOLFast(_PREHASH_GroupOwned, mIsGroupOwned);
+}
+
+void LLPermissions::unpackMessage(LLSD perms)
+{
+ mCreator = perms["creator-id"];
+ mOwner = perms["owner-id"];
+ mGroup = perms["group-id"];
+
+ mMaskBase = (U32)perms["base-mask"].asInteger();
+ mMaskOwner = (U32)perms["owner-mask"].asInteger();
+ mMaskGroup = (U32)perms["group-mask"].asInteger();
+ mMaskEveryone = (U32)perms["everyone-mask"].asInteger();
+ mMaskNextOwner = (U32)perms["next-owner-mask"].asInteger();
+ mIsGroupOwned = perms["group-owned"].asBoolean();
+}
+
+void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num)
+{
+ msg->getUUIDFast(block, _PREHASH_CreatorID, mCreator, block_num);
+ msg->getUUIDFast(block, _PREHASH_OwnerID, mOwner, block_num);
+ msg->getUUIDFast(block, _PREHASH_GroupID, mGroup, block_num);
+
+ msg->getU32Fast(block, _PREHASH_BaseMask, mMaskBase, block_num );
+ msg->getU32Fast(block, _PREHASH_OwnerMask, mMaskOwner, block_num );
+ msg->getU32Fast(block, _PREHASH_GroupMask, mMaskGroup, block_num );
+ msg->getU32Fast(block, _PREHASH_EveryoneMask, mMaskEveryone, block_num );
+ msg->getU32Fast(block, _PREHASH_NextOwnerMask, mMaskNextOwner, block_num );
+ bool tmp;
+ msg->getBOOLFast(block, _PREHASH_GroupOwned, tmp, block_num);
+ mIsGroupOwned = tmp;
+}
+
+
+bool LLPermissions::importLegacyStream(std::istream& input_stream)
+{
+ init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
+ const S32 BUFSIZE = 16384;
+
+ // *NOTE: Changing the buffer size will require changing the scanf
+ // calls below.
+ char buffer[BUFSIZE]; /* Flawfinder: ignore */
+ char keyword[256]; /* Flawfinder: ignore */
+ char valuestr[256]; /* Flawfinder: ignore */
+ char uuid_str[256]; /* Flawfinder: ignore */
+ U32 mask;
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+
+ while (input_stream.good())
+ {
+ input_stream.getline(buffer, BUFSIZE);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %255s %255s",
+ keyword, valuestr);
+ if (!strcmp("{", keyword))
+ {
+ continue;
+ }
+ if (!strcmp("}",keyword))
+ {
+ break;
+ }
+ else if (!strcmp("creator_mask", keyword))
+ {
+ // legacy support for "creator" masks
+ sscanf(valuestr, "%x", &mask);
+ mMaskBase = mask;
+ fixFairUse();
+ }
+ else if (!strcmp("base_mask", keyword))
+ {
+ sscanf(valuestr, "%x", &mask);
+ mMaskBase = mask;
+ //fixFairUse();
+ }
+ else if (!strcmp("owner_mask", keyword))
+ {
+ sscanf(valuestr, "%x", &mask);
+ mMaskOwner = mask;
+ }
+ else if (!strcmp("group_mask", keyword))
+ {
+ sscanf(valuestr, "%x", &mask);
+ mMaskGroup = mask;
+ }
+ else if (!strcmp("everyone_mask", keyword))
+ {
+ sscanf(valuestr, "%x", &mask);
+ mMaskEveryone = mask;
+ }
+ else if (!strcmp("next_owner_mask", keyword))
+ {
+ sscanf(valuestr, "%x", &mask);
+ mMaskNextOwner = mask;
+ }
+ else if (!strcmp("creator_id", keyword))
+ {
+ sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
+ mCreator.set(uuid_str);
+ }
+ else if (!strcmp("owner_id", keyword))
+ {
+ sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
+ mOwner.set(uuid_str);
+ }
+ else if (!strcmp("last_owner_id", keyword))
+ {
+ sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
+ mLastOwner.set(uuid_str);
+ }
+ else if (!strcmp("group_id", keyword))
+ {
+ sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
+ mGroup.set(uuid_str);
+ }
+ else if (!strcmp("group_owned", keyword))
+ {
+ sscanf(valuestr, "%d", &mask);
+ if(mask) mIsGroupOwned = true;
+ else mIsGroupOwned = false;
+ }
+ else
+ {
+ LL_INFOS() << "unknown keyword " << keyword << " in permissions import" << LL_ENDL;
+ }
+ }
+ fix();
+ return true;
+}
+
+
+bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const
+{
+ std::string uuid_str;
+
+ output_stream << "\tpermissions 0\n";
+ output_stream << "\t{\n";
+
+ std::string buffer;
+ buffer = llformat( "\t\tbase_mask\t%08x\n", mMaskBase);
+ output_stream << buffer;
+ buffer = llformat( "\t\towner_mask\t%08x\n", mMaskOwner);
+ output_stream << buffer;
+ buffer = llformat( "\t\tgroup_mask\t%08x\n", mMaskGroup);
+ output_stream << buffer;
+ buffer = llformat( "\t\teveryone_mask\t%08x\n", mMaskEveryone);
+ output_stream << buffer;
+ buffer = llformat( "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
+ output_stream << buffer;
+
+ mCreator.toString(uuid_str);
+ output_stream << "\t\tcreator_id\t" << uuid_str << "\n";
+
+ mOwner.toString(uuid_str);
+ output_stream << "\t\towner_id\t" << uuid_str << "\n";
+
+ mLastOwner.toString(uuid_str);
+ output_stream << "\t\tlast_owner_id\t" << uuid_str << "\n";
+
+ mGroup.toString(uuid_str);
+ output_stream << "\t\tgroup_id\t" << uuid_str << "\n";
+
+ if(mIsGroupOwned)
+ {
+ output_stream << "\t\tgroup_owned\t1\n";
+ }
+ output_stream << "\t}\n";
+ return true;
+}
+
+bool LLPermissions::operator==(const LLPermissions &rhs) const
+{
+ return
+ (mCreator == rhs.mCreator) &&
+ (mOwner == rhs.mOwner) &&
+ (mLastOwner == rhs.mLastOwner ) &&
+ (mGroup == rhs.mGroup ) &&
+ (mMaskBase == rhs.mMaskBase ) &&
+ (mMaskOwner == rhs.mMaskOwner ) &&
+ (mMaskGroup == rhs.mMaskGroup ) &&
+ (mMaskEveryone == rhs.mMaskEveryone ) &&
+ (mMaskNextOwner == rhs.mMaskNextOwner ) &&
+ (mIsGroupOwned == rhs.mIsGroupOwned);
+}
+
+
+bool LLPermissions::operator!=(const LLPermissions &rhs) const
+{
+ return
+ (mCreator != rhs.mCreator) ||
+ (mOwner != rhs.mOwner) ||
+ (mLastOwner != rhs.mLastOwner ) ||
+ (mGroup != rhs.mGroup ) ||
+ (mMaskBase != rhs.mMaskBase ) ||
+ (mMaskOwner != rhs.mMaskOwner ) ||
+ (mMaskGroup != rhs.mMaskGroup ) ||
+ (mMaskEveryone != rhs.mMaskEveryone ) ||
+ (mMaskNextOwner != rhs.mMaskNextOwner) ||
+ (mIsGroupOwned != rhs.mIsGroupOwned);
+}
+
+std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)
+{
+ s << "{Creator=" << perm.getCreator();
+ s << ", Owner=" << perm.getOwner();
+ s << ", Group=" << perm.getGroup();
+ s << std::hex << ", BaseMask=0x" << perm.getMaskBase();
+ s << ", OwnerMask=0x" << perm.getMaskOwner();
+ s << ", EveryoneMask=0x" << perm.getMaskEveryone();
+ s << ", GroupMask=0x" << perm.getMaskGroup();
+ s << ", NextOwnerMask=0x" << perm.getMaskNextOwner() << std::dec;
+ s << "}";
+ return s;
+}
+
+///----------------------------------------------------------------------------
+/// Class LLAggregatePermissions
+///----------------------------------------------------------------------------
+
+const LLAggregatePermissions LLAggregatePermissions::empty;
+
+
+LLAggregatePermissions::LLAggregatePermissions()
+{
+ for(S32 i = 0; i < PI_COUNT; ++i)
+ {
+ mBits[i] = AP_EMPTY;
+ }
+}
+
+LLAggregatePermissions::EValue LLAggregatePermissions::getValue(PermissionBit bit) const
+{
+ EPermIndex idx = perm2PermIndex(bit);
+ EValue rv = AP_EMPTY;
+ if(idx != PI_END)
+ {
+ rv = (LLAggregatePermissions::EValue)(mBits[idx]);
+ }
+ return rv;
+}
+
+// returns the bits compressed into a single byte: 00TTMMCC
+// where TT = transfer, MM = modify, and CC = copy
+// LSB is to the right
+U8 LLAggregatePermissions::getU8() const
+{
+ U8 byte = mBits[PI_TRANSFER];
+ byte <<= 2;
+ byte |= mBits[PI_MODIFY];
+ byte <<= 2;
+ byte |= mBits[PI_COPY];
+ return byte;
+}
+
+bool LLAggregatePermissions::isEmpty() const
+{
+ for(S32 i = 0; i < PI_END; ++i)
+ {
+ if(mBits[i] != AP_EMPTY)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+void LLAggregatePermissions::aggregate(PermissionMask mask)
+{
+ bool is_allowed = mask & PERM_COPY;
+ aggregateBit(PI_COPY, is_allowed);
+ is_allowed = mask & PERM_MODIFY;
+ aggregateBit(PI_MODIFY, is_allowed);
+ is_allowed = mask & PERM_TRANSFER;
+ aggregateBit(PI_TRANSFER, is_allowed);
+}
+
+void LLAggregatePermissions::aggregate(const LLAggregatePermissions& ag)
+{
+ for(S32 idx = PI_COPY; idx != PI_END; ++idx)
+ {
+ aggregateIndex((EPermIndex)idx, ag.mBits[idx]);
+ }
+}
+
+void LLAggregatePermissions::aggregateBit(EPermIndex idx, bool allowed)
+{
+ //if(AP_SOME == mBits[idx]) return; // P4 branch prediction optimization
+ switch(mBits[idx])
+ {
+ case AP_EMPTY:
+ mBits[idx] = allowed ? AP_ALL : AP_NONE;
+ break;
+ case AP_NONE:
+ mBits[idx] = allowed ? AP_SOME: AP_NONE;
+ break;
+ case AP_SOME:
+ // no-op
+ break;
+ case AP_ALL:
+ mBits[idx] = allowed ? AP_ALL : AP_SOME;
+ break;
+ default:
+ LL_WARNS() << "Bad aggregateBit " << (S32)idx << " "
+ << (allowed ? "true" : "false") << LL_ENDL;
+ break;
+ }
+}
+
+void LLAggregatePermissions::aggregateIndex(EPermIndex idx, U8 bits)
+{
+ switch(mBits[idx])
+ {
+ case AP_EMPTY:
+ mBits[idx] = bits;
+ break;
+ case AP_NONE:
+ switch(bits)
+ {
+ case AP_SOME:
+ case AP_ALL:
+ mBits[idx] = AP_SOME;
+ break;
+ case AP_EMPTY:
+ case AP_NONE:
+ default:
+ // no-op
+ break;
+ }
+ break;
+ case AP_SOME:
+ // no-op
+ break;
+ case AP_ALL:
+ switch(bits)
+ {
+ case AP_NONE:
+ case AP_SOME:
+ mBits[idx] = AP_SOME;
+ break;
+ case AP_EMPTY:
+ case AP_ALL:
+ default:
+ // no-op
+ break;
+ }
+ break;
+ default:
+ LL_WARNS() << "Bad aggregate index " << (S32)idx << " "
+ << (S32)bits << LL_ENDL;
+ break;
+ }
+}
+
+// static
+LLAggregatePermissions::EPermIndex LLAggregatePermissions::perm2PermIndex(PermissionBit bit)
+{
+ EPermIndex idx = PI_END; // past any good value.
+ switch(bit)
+ {
+ case PERM_COPY:
+ idx = PI_COPY;
+ break;
+ case PERM_MODIFY:
+ idx = PI_MODIFY;
+ break;
+ case PERM_TRANSFER:
+ idx = PI_TRANSFER;
+ break;
+ default:
+ break;
+ }
+ return idx;
+}
+
+
+void LLAggregatePermissions::packMessage(LLMessageSystem* msg, const char* field) const
+{
+ msg->addU8Fast(field, getU8());
+}
+
+void LLAggregatePermissions::unpackMessage(LLMessageSystem* msg, const char* block, const char* field, S32 block_num)
+{
+ const U8 TWO_BITS = 0x3; // binary 00000011
+ U8 bits = 0;
+ msg->getU8Fast(block, field, bits, block_num);
+ mBits[PI_COPY] = bits & TWO_BITS;
+ bits >>= 2;
+ mBits[PI_MODIFY] = bits & TWO_BITS;
+ bits >>= 2;
+ mBits[PI_TRANSFER] = bits & TWO_BITS;
+}
+
+const std::string AGGREGATE_VALUES[4] =
+ {
+ std::string( "Empty" ),
+ std::string( "None" ),
+ std::string( "Some" ),
+ std::string( "All" )
+ };
+
+std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm)
+{
+ s << "{PI_COPY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_COPY]];
+ s << ", PI_MODIFY=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_MODIFY]];
+ s << ", PI_TRANSFER=" << AGGREGATE_VALUES[perm.mBits[LLAggregatePermissions::PI_TRANSFER]];
+ s << "}";
+ return s;
+}
+
+// This converts a permissions mask into a string for debugging use.
+void mask_to_string(U32 mask, char* str)
+{
+ if (mask & PERM_MOVE)
+ {
+ *str = 'V';
+ }
+ else
+ {
+ *str = ' ';
+ }
+ str++;
+
+ if (mask & PERM_MODIFY)
+ {
+ *str = 'M';
+ }
+ else
+ {
+ *str = ' ';
+ }
+ str++;
+
+ if (mask & PERM_COPY)
+ {
+ *str = 'C';
+ }
+ else
+ {
+ *str = ' ';
+ }
+ str++;
+
+ if (mask & PERM_TRANSFER)
+ {
+ *str = 'T';
+ }
+ else
+ {
+ *str = ' ';
+ }
+ str++;
+ *str = '\0';
+}
+
+std::string mask_to_string(U32 mask)
+{
+ char str[16];
+ mask_to_string(mask, str);
+ return std::string(str);
+}
+
+///----------------------------------------------------------------------------
+/// exported functions
+///----------------------------------------------------------------------------
+static const std::string PERM_CREATOR_ID_LABEL("creator_id");
+static const std::string PERM_OWNER_ID_LABEL("owner_id");
+static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
+static const std::string PERM_GROUP_ID_LABEL("group_id");
+static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
+static const std::string PERM_BASE_MASK_LABEL("base_mask");
+static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
+static const std::string PERM_GROUP_MASK_LABEL("group_mask");
+static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
+static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
+
+LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
+{
+ LLSD rv;
+ rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
+ rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
+ rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
+ rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
+ rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
+ rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
+ rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
+ rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
+ rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
+ rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
+ return rv;
+}
+
+LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
+{
+ LLPermissions rv;
+ rv.init(
+ sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
+ sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
+ sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
+ sd_perm[PERM_GROUP_ID_LABEL].asUUID());
+
+ // We do a cast to U32 here since LLSD does not attempt to
+ // represent unsigned ints.
+ PermissionMask mask;
+ mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
+ rv.setMaskBase(mask);
+ mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
+ rv.setMaskOwner(mask);
+ mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
+ rv.setMaskEveryone(mask);
+ mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
+ rv.setMaskGroup(mask);
+ mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
+ rv.setMaskNext(mask);
+ rv.fix();
+ return rv;
+}
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 4f6920f27a..e4baf2ff68 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -1,450 +1,450 @@ -/** - * @file llpermissions.h - * @brief Permissions structures for objects. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLPERMISSIONS_H -#define LL_LLPERMISSIONS_H - -#include "llpermissionsflags.h" -#include "llsd.h" -#include "lluuid.h" -#include "llxmlnode.h" -#include "llinventorytype.h" - -// prototypes -class LLMessageSystem; -extern void mask_to_string(U32 mask, char* str); -extern std::string mask_to_string(U32 mask); -template<class T> class LLMetaClassT; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLPermissions -// -// Class which encapsulates object and inventory permissions/ownership/etc. -// -// Permissions where originally a static state creator/owner and set -// of cap bits. Since then, it has grown to include group information, -// last owner, masks for different people. The implementation has been -// chosen such that a uuid is stored for each current/past owner, and -// a bitmask is stored for the base permissions, owner permissions, -// group permissions, and everyone else permissions. -// -// The base permissions represent the most permissive state that the -// permissions can possibly be in. Thus, if the base permissions do -// not allow copying, no one can ever copy the object. The permissions -// also maintain a tree-like hierarchy of permissions, thus, if we -// (for sake of discussions) denote more permissive as '>', then this -// is invariant: -// -// base mask >= owner mask >= group mask -// >= everyone mask -// >= next owner mask -// NOTE: the group mask does not effect everyone or next, everyone -// does not effect group or next, etc. -// -// It is considered a fair use right to move or delete any object you -// own. Another fair use right is the ability to give away anything -// which you cannot copy. One way to look at that is that if you have -// a unique item, you can always give that one copy you have to -// someone else. -// -// Most of the bitmask is easy to understand, PERM_COPY means you can -// copy !PERM_TRANSFER means you cannot transfer, etc. Given that we -// now track the concept of 'next owner' inside of the permissions -// object, we can describe some new meta-meaning to the PERM_MODIFY -// flag. PERM_MODIFY is usually meant to note if you can change an -// item, but since we record next owner permissions, we can interpret -// a no-modify object as 'you cannot modify this object and you cannot -// make derivative works.' When evaluating functionality, and -// comparisons against permissions, keep this concept in mind for -// logical consistency. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLPermissions -{ -private: - LLUUID mCreator; // null if object created by system - LLUUID mOwner; // null if object "unowned" (owned by system) - LLUUID mLastOwner; // object's last owner - LLUUID mGroup; // The group association - - PermissionMask mMaskBase; // initially permissive, progressively AND restricted by each owner - - PermissionMask mMaskOwner; // set by owner, applies to owner only, restricts lower permissions - PermissionMask mMaskEveryone; // set by owner, applies to everyone else - - PermissionMask mMaskGroup; // set by owner, applies to group that is associated with permissions - - PermissionMask mMaskNextOwner; // set by owner, applied to base on transfer. - - // Usually set in the fixOwnership() method based on current uuid - // values. - bool mIsGroupOwned; - - // Correct for fair use - you can never take away the right to - // move stuff you own, and you can never take away the right to - // transfer something you cannot otherwise copy. - void fixFairUse(); - - // Fix internal consistency for group/agent ownership - void fixOwnership(); - -public: - static const LLPermissions DEFAULT; - - LLPermissions(); // defaults to created by system - //~LLPermissions(); - - // base initialization code - void init(const LLUUID& creator, const LLUUID& owner, - const LLUUID& last_owner, const LLUUID& group); - void initMasks(PermissionMask base, PermissionMask owner, - PermissionMask everyone, PermissionMask group, - PermissionMask next); - // adjust permissions based on inventory type. - void initMasks(LLInventoryType::EType type); - - // - // ACCESSORS - // - - // return the agent_id of the agent that created the item - const LLUUID& getCreator() const { return mCreator; } - - // return the agent_id of the owner. returns LLUUID::null if group - // owned or public (a really big group). - const LLUUID& getOwner() const { return mOwner; } - - // return the group_id of the group associated with the - // object. - const LLUUID& getGroup() const { return mGroup; } - - // return the agent_id of the last agent owner. Only returns - // LLUUID::null if there has never been a previous owner (*note: this is apparently not true, say for textures in inventory, it may return LLUUID::null even if there was a previous owner). - const LLUUID& getLastOwner() const { return mLastOwner; } - - U32 getMaskBase() const { return mMaskBase; } - U32 getMaskOwner() const { return mMaskOwner; } - U32 getMaskGroup() const { return mMaskGroup; } - U32 getMaskEveryone() const { return mMaskEveryone; } - U32 getMaskNextOwner() const { return mMaskNextOwner; } - - // return true if the object has any owner - bool isOwned() const { return (mOwner.notNull() || mIsGroupOwned); } - - // return true if group_id is owner. - bool isGroupOwned() const { return mIsGroupOwned; } - - // This API returns true if the object is owned at all, and false - // otherwise. If it is owned at all, owner id is filled with - // either the owner id or the group id, and the is_group_owned - // parameter is appropriately filled. The values of owner_id and - // is_group_owned are not changed if the object is not owned. - bool getOwnership(LLUUID& owner_id, bool& is_group_owned) const; - - // Gets the 'safe' owner. This should never return LLUUID::null. - // If no group owned, return the agent owner id normally. - // If group owned, return the group id. - // If not owned, return a random uuid which should have no power. - LLUUID getSafeOwner() const; - - // return a cheap crc - U32 getCRC32() const; - - - // - // MANIPULATORS - // - - // Fix hierarchy of permissions, applies appropriate permissions - // at each level to ensure that base permissions are respected, - // and also ensures that if base cannot transfer, then group and - // other cannot copy. - void fix(); - - // All of these methods just do exactly what they say. There is no - // permissions checking to see if the operation is allowed, and do - // not fix the permissions hierarchy. So please only use these - // methods when you are know what you're doing and coding on - // behalf of the system - ie, acting as god. - void set(const LLPermissions& permissions); - void setMaskBase(U32 mask) { mMaskBase = mask; } - void setMaskOwner(U32 mask) { mMaskOwner = mask; } - void setMaskEveryone(U32 mask) { mMaskEveryone = mask;} - void setMaskGroup(U32 mask) { mMaskGroup = mask;} - void setMaskNext(U32 mask) { mMaskNextOwner = mask; } - - // Allow accumulation of permissions. Results in the tightest - // permissions possible. In the case of clashing UUIDs, it sets - // the ID to LLUUID::null. - void accumulate(const LLPermissions& perm); - - // - // CHECKED MANIPULATORS - // - - // These functions return true on success. They return false if - // the given agent isn't allowed to make the change. You can pass - // LLUUID::null as the agent id if the change is being made by the - // simulator itself, not on behalf of any agent - this will always - // succeed. Passing in group id of LLUUID:null means no group, and - // does not offer special permission to do anything. - - // saves last owner, sets current owner, and sets the group. - // set is_atomic = true means that this permission represents - // an atomic permission and not a collection of permissions. - // Currently, the only way to have a collection is when an object - // has inventory and is then itself rolled up into an inventory - // item. - bool setOwnerAndGroup(const LLUUID& agent, const LLUUID& owner, const LLUUID& group, bool is_atomic); - - // only call this if you know what you're doing - // there are usually perm-bit consequences when the - // ownerhsip changes - void yesReallySetOwner(const LLUUID& owner, bool group_owned); - - // Last owner doesn't have much in the way of permissions so it's - //not too dangerous to do this. - void setLastOwner(const LLUUID& last_owner); - - // saves last owner, sets owner to uuid null, sets group - // owned. group_id must be the group of the object (that's who it - // is being deeded to) and the object must be group - // modify. Technically, the agent id and group id are not - // necessary, but I wanted this function to look like the other - // checked manipulators (since that is how it is used.) If the - // agent is the system or (group == mGroup and group modify and - // owner transfer) then this function will deed the permissions, - // set the next owner mask, and return true. Otherwise, no change - // is effected, and the function returns false. - bool deedToGroup(const LLUUID& agent, const LLUUID& group); - // Attempt to set or clear the given bitmask. Returns true if you - // are allowed to modify the permissions. If you attempt to turn - // on bits not allowed by the base bits, the function will return - // true, but those bits will not be set. - bool setBaseBits( const LLUUID& agent, bool set, PermissionMask bits); - bool setOwnerBits( const LLUUID& agent, bool set, PermissionMask bits); - bool setGroupBits( const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits); - bool setEveryoneBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits); - bool setNextOwnerBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits); - - // This is currently only used in the Viewer to handle calling cards - // where the creator is actually used to store the target. Use with care. - void setCreator(const LLUUID& creator) { mCreator = creator; } - - // - // METHODS - // - - // All the allow* functions return true if the given agent or - // group can perform the function. Prefer using this set of - // operations to check permissions on an object. These return - // true if the given agent or group can perform the function. - // They also return true if the object isn't owned, or the - // requesting agent is a system agent. See llpermissionsflags.h - // for bits. - bool allowOperationBy(PermissionBit op, const LLUUID& agent, const LLUUID& group = LLUUID::null) const; - - inline bool allowModifyBy(const LLUUID &agent_id) const; - inline bool allowCopyBy(const LLUUID& agent_id) const; - inline bool allowMoveBy(const LLUUID& agent_id) const; - inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const; - inline bool allowCopyBy(const LLUUID& agent_id, const LLUUID& group) const; - inline bool allowMoveBy(const LLUUID &agent_id, const LLUUID &group) 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; - - // - // DEPRECATED. - // - // These return true if the given agent can perform the function. - // They also return true if the object isn't owned, or the - // requesting agent is a system agent. See llpermissionsflags.h - // for bits. - //bool allowDeleteBy(const LLUUID& agent_id) const { return allowModifyBy(agent_id); } - //bool allowEditBy(const LLUUID& agent_id) const { return allowModifyBy(agent_id); } - // saves last owner and sets current owner - //bool setOwner(const LLUUID& agent, const LLUUID& owner); - // This method saves the last owner, sets the current owner to the - // one provided, and sets the base mask as indicated. - //bool setOwner(const LLUUID& agent, const LLUUID& owner, U32 new_base_mask); - - // Attempt to set or clear the given bitmask. Returns true if you - // are allowed to modify the permissions. If you attempt to turn - // on bits not allowed by the base bits, the function will return - // true, but those bits will not be set. - //bool setGroupBits( const LLUUID& agent, bool set, PermissionMask bits); - //bool setEveryoneBits(const LLUUID& agent, bool set, PermissionMask bits); - - // - // MISC METHODS and OPERATORS - // - - LLSD packMessage() const; - void unpackMessage(LLSD perms); - - // For messaging system support - void packMessage(LLMessageSystem* msg) const; - void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); - - bool importLegacyStream(std::istream& input_stream); - bool exportLegacyStream(std::ostream& output_stream) const; - - bool operator==(const LLPermissions &rhs) const; - bool operator!=(const LLPermissions &rhs) const; - - friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm); - -}; - -// Inlines -bool LLPermissions::allowModifyBy(const LLUUID& agent, const LLUUID& group) const -{ - return allowOperationBy(PERM_MODIFY, agent, group); -} - -bool LLPermissions::allowCopyBy(const LLUUID& agent, const LLUUID& group) const -{ - return allowOperationBy(PERM_COPY, agent, group); -} - - -bool LLPermissions::allowMoveBy(const LLUUID& agent, const LLUUID& group) const -{ - return allowOperationBy(PERM_MOVE, agent, group); -} - -bool LLPermissions::allowModifyBy(const LLUUID& agent) const -{ - return allowOperationBy(PERM_MODIFY, agent, LLUUID::null); -} - -bool LLPermissions::allowCopyBy(const LLUUID& agent) const -{ - return allowOperationBy(PERM_COPY, agent, LLUUID::null); -} - -bool LLPermissions::allowMoveBy(const LLUUID& agent) const -{ - return allowOperationBy(PERM_MOVE, agent, LLUUID::null); -} - -bool LLPermissions::allowTransferTo(const LLUUID &agent_id) const -{ - if (mIsGroupOwned) - { - return allowOperationBy(PERM_TRANSFER, mGroup, mGroup); - } - else - { - return ((mOwner == agent_id) ? true : allowOperationBy(PERM_TRANSFER, mOwner)); - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLAggregatePermissions -// -// Class which encapsulates object and inventory permissions, -// ownership, etc. Currently, it only aggregates PERM_COPY, -// PERM_MODIFY, and PERM_TRANSFER. -// -// Usually you will construct an instance and hand the object several -// permissions masks to aggregate the copy, modify, and -// transferability into a nice trinary value. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLAggregatePermissions -{ -public: - enum EValue - { - AP_EMPTY = 0x00, - AP_NONE = 0x01, - AP_SOME = 0x02, - AP_ALL = 0x03 - }; - - // construct an empty aggregate permissions - LLAggregatePermissions(); - - // pass in a PERM_COPY, PERM_TRANSFER, etc, and get out a EValue - // enumeration describing the current aggregate permissions. - EValue getValue(PermissionBit bit) const; - - // returns the permissions packed into the 6 LSB of a U8: - // 00TTMMCC - // where TT = transfer, MM = modify, and CC = copy - // LSB is to the right - U8 getU8() const; - - // return true is the aggregate permissions are empty, otherwise false. - bool isEmpty() const ; - - // pass in a PERM_COPY, PERM_TRANSFER, etc, and an EValue - // enumeration to specifically set that value. Not implemented - // because I'm not sure it's a useful api. - //void setValue(PermissionBit bit, EValue); - - // Given a mask, aggregate the useful permissions. - void aggregate(PermissionMask mask); - - // Aggregate aggregates - void aggregate(const LLAggregatePermissions& ag); - - // message handling - void packMessage(LLMessageSystem* msg, const char* field) const; - void unpackMessage(LLMessageSystem* msg, const char* block, const char *field, S32 block_num = 0); - - static const LLAggregatePermissions empty; - - friend std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm); - -protected: - enum EPermIndex - { - PI_COPY = 0, - PI_MODIFY = 1, - PI_TRANSFER = 2, - PI_END = 3, - PI_COUNT = 3 - }; - void aggregateBit(EPermIndex idx, bool allowed); - void aggregateIndex(EPermIndex idx, U8 bits); - static EPermIndex perm2PermIndex(PermissionBit bit); - - // structure used to store the aggregate so far. - U8 mBits[PI_COUNT]; -}; - -// These functions convert between structured data and permissions as -// appropriate for serialization. The permissions are a map of things -// like 'creator_id', 'owner_id', etc, with the value copied from the -// permission object. -LLSD ll_create_sd_from_permissions(const LLPermissions& perm); -LLPermissions ll_permissions_from_sd(const LLSD& sd_perm); - -#endif +/**
+ * @file llpermissions.h
+ * @brief Permissions structures for objects.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPERMISSIONS_H
+#define LL_LLPERMISSIONS_H
+
+#include "llpermissionsflags.h"
+#include "llsd.h"
+#include "lluuid.h"
+#include "llxmlnode.h"
+#include "llinventorytype.h"
+
+// prototypes
+class LLMessageSystem;
+extern void mask_to_string(U32 mask, char* str);
+extern std::string mask_to_string(U32 mask);
+template<class T> class LLMetaClassT;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLPermissions
+//
+// Class which encapsulates object and inventory permissions/ownership/etc.
+//
+// Permissions where originally a static state creator/owner and set
+// of cap bits. Since then, it has grown to include group information,
+// last owner, masks for different people. The implementation has been
+// chosen such that a uuid is stored for each current/past owner, and
+// a bitmask is stored for the base permissions, owner permissions,
+// group permissions, and everyone else permissions.
+//
+// The base permissions represent the most permissive state that the
+// permissions can possibly be in. Thus, if the base permissions do
+// not allow copying, no one can ever copy the object. The permissions
+// also maintain a tree-like hierarchy of permissions, thus, if we
+// (for sake of discussions) denote more permissive as '>', then this
+// is invariant:
+//
+// base mask >= owner mask >= group mask
+// >= everyone mask
+// >= next owner mask
+// NOTE: the group mask does not effect everyone or next, everyone
+// does not effect group or next, etc.
+//
+// It is considered a fair use right to move or delete any object you
+// own. Another fair use right is the ability to give away anything
+// which you cannot copy. One way to look at that is that if you have
+// a unique item, you can always give that one copy you have to
+// someone else.
+//
+// Most of the bitmask is easy to understand, PERM_COPY means you can
+// copy !PERM_TRANSFER means you cannot transfer, etc. Given that we
+// now track the concept of 'next owner' inside of the permissions
+// object, we can describe some new meta-meaning to the PERM_MODIFY
+// flag. PERM_MODIFY is usually meant to note if you can change an
+// item, but since we record next owner permissions, we can interpret
+// a no-modify object as 'you cannot modify this object and you cannot
+// make derivative works.' When evaluating functionality, and
+// comparisons against permissions, keep this concept in mind for
+// logical consistency.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLPermissions
+{
+private:
+ LLUUID mCreator; // null if object created by system
+ LLUUID mOwner; // null if object "unowned" (owned by system)
+ LLUUID mLastOwner; // object's last owner
+ LLUUID mGroup; // The group association
+
+ PermissionMask mMaskBase; // initially permissive, progressively AND restricted by each owner
+
+ PermissionMask mMaskOwner; // set by owner, applies to owner only, restricts lower permissions
+ PermissionMask mMaskEveryone; // set by owner, applies to everyone else
+
+ PermissionMask mMaskGroup; // set by owner, applies to group that is associated with permissions
+
+ PermissionMask mMaskNextOwner; // set by owner, applied to base on transfer.
+
+ // Usually set in the fixOwnership() method based on current uuid
+ // values.
+ bool mIsGroupOwned;
+
+ // Correct for fair use - you can never take away the right to
+ // move stuff you own, and you can never take away the right to
+ // transfer something you cannot otherwise copy.
+ void fixFairUse();
+
+ // Fix internal consistency for group/agent ownership
+ void fixOwnership();
+
+public:
+ static const LLPermissions DEFAULT;
+
+ LLPermissions(); // defaults to created by system
+ //~LLPermissions();
+
+ // base initialization code
+ void init(const LLUUID& creator, const LLUUID& owner,
+ const LLUUID& last_owner, const LLUUID& group);
+ void initMasks(PermissionMask base, PermissionMask owner,
+ PermissionMask everyone, PermissionMask group,
+ PermissionMask next);
+ // adjust permissions based on inventory type.
+ void initMasks(LLInventoryType::EType type);
+
+ //
+ // ACCESSORS
+ //
+
+ // return the agent_id of the agent that created the item
+ const LLUUID& getCreator() const { return mCreator; }
+
+ // return the agent_id of the owner. returns LLUUID::null if group
+ // owned or public (a really big group).
+ const LLUUID& getOwner() const { return mOwner; }
+
+ // return the group_id of the group associated with the
+ // object.
+ const LLUUID& getGroup() const { return mGroup; }
+
+ // return the agent_id of the last agent owner. Only returns
+ // LLUUID::null if there has never been a previous owner (*note: this is apparently not true, say for textures in inventory, it may return LLUUID::null even if there was a previous owner).
+ const LLUUID& getLastOwner() const { return mLastOwner; }
+
+ U32 getMaskBase() const { return mMaskBase; }
+ U32 getMaskOwner() const { return mMaskOwner; }
+ U32 getMaskGroup() const { return mMaskGroup; }
+ U32 getMaskEveryone() const { return mMaskEveryone; }
+ U32 getMaskNextOwner() const { return mMaskNextOwner; }
+
+ // return true if the object has any owner
+ bool isOwned() const { return (mOwner.notNull() || mIsGroupOwned); }
+
+ // return true if group_id is owner.
+ bool isGroupOwned() const { return mIsGroupOwned; }
+
+ // This API returns true if the object is owned at all, and false
+ // otherwise. If it is owned at all, owner id is filled with
+ // either the owner id or the group id, and the is_group_owned
+ // parameter is appropriately filled. The values of owner_id and
+ // is_group_owned are not changed if the object is not owned.
+ bool getOwnership(LLUUID& owner_id, bool& is_group_owned) const;
+
+ // Gets the 'safe' owner. This should never return LLUUID::null.
+ // If no group owned, return the agent owner id normally.
+ // If group owned, return the group id.
+ // If not owned, return a random uuid which should have no power.
+ LLUUID getSafeOwner() const;
+
+ // return a cheap crc
+ U32 getCRC32() const;
+
+
+ //
+ // MANIPULATORS
+ //
+
+ // Fix hierarchy of permissions, applies appropriate permissions
+ // at each level to ensure that base permissions are respected,
+ // and also ensures that if base cannot transfer, then group and
+ // other cannot copy.
+ void fix();
+
+ // All of these methods just do exactly what they say. There is no
+ // permissions checking to see if the operation is allowed, and do
+ // not fix the permissions hierarchy. So please only use these
+ // methods when you are know what you're doing and coding on
+ // behalf of the system - ie, acting as god.
+ void set(const LLPermissions& permissions);
+ void setMaskBase(U32 mask) { mMaskBase = mask; }
+ void setMaskOwner(U32 mask) { mMaskOwner = mask; }
+ void setMaskEveryone(U32 mask) { mMaskEveryone = mask;}
+ void setMaskGroup(U32 mask) { mMaskGroup = mask;}
+ void setMaskNext(U32 mask) { mMaskNextOwner = mask; }
+
+ // Allow accumulation of permissions. Results in the tightest
+ // permissions possible. In the case of clashing UUIDs, it sets
+ // the ID to LLUUID::null.
+ void accumulate(const LLPermissions& perm);
+
+ //
+ // CHECKED MANIPULATORS
+ //
+
+ // These functions return true on success. They return false if
+ // the given agent isn't allowed to make the change. You can pass
+ // LLUUID::null as the agent id if the change is being made by the
+ // simulator itself, not on behalf of any agent - this will always
+ // succeed. Passing in group id of LLUUID:null means no group, and
+ // does not offer special permission to do anything.
+
+ // saves last owner, sets current owner, and sets the group.
+ // set is_atomic = true means that this permission represents
+ // an atomic permission and not a collection of permissions.
+ // Currently, the only way to have a collection is when an object
+ // has inventory and is then itself rolled up into an inventory
+ // item.
+ bool setOwnerAndGroup(const LLUUID& agent, const LLUUID& owner, const LLUUID& group, bool is_atomic);
+
+ // only call this if you know what you're doing
+ // there are usually perm-bit consequences when the
+ // ownerhsip changes
+ void yesReallySetOwner(const LLUUID& owner, bool group_owned);
+
+ // Last owner doesn't have much in the way of permissions so it's
+ //not too dangerous to do this.
+ void setLastOwner(const LLUUID& last_owner);
+
+ // saves last owner, sets owner to uuid null, sets group
+ // owned. group_id must be the group of the object (that's who it
+ // is being deeded to) and the object must be group
+ // modify. Technically, the agent id and group id are not
+ // necessary, but I wanted this function to look like the other
+ // checked manipulators (since that is how it is used.) If the
+ // agent is the system or (group == mGroup and group modify and
+ // owner transfer) then this function will deed the permissions,
+ // set the next owner mask, and return true. Otherwise, no change
+ // is effected, and the function returns false.
+ bool deedToGroup(const LLUUID& agent, const LLUUID& group);
+ // Attempt to set or clear the given bitmask. Returns true if you
+ // are allowed to modify the permissions. If you attempt to turn
+ // on bits not allowed by the base bits, the function will return
+ // true, but those bits will not be set.
+ bool setBaseBits( const LLUUID& agent, bool set, PermissionMask bits);
+ bool setOwnerBits( const LLUUID& agent, bool set, PermissionMask bits);
+ bool setGroupBits( const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits);
+ bool setEveryoneBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits);
+ bool setNextOwnerBits(const LLUUID& agent, const LLUUID& group, bool set, PermissionMask bits);
+
+ // This is currently only used in the Viewer to handle calling cards
+ // where the creator is actually used to store the target. Use with care.
+ void setCreator(const LLUUID& creator) { mCreator = creator; }
+
+ //
+ // METHODS
+ //
+
+ // All the allow* functions return true if the given agent or
+ // group can perform the function. Prefer using this set of
+ // operations to check permissions on an object. These return
+ // true if the given agent or group can perform the function.
+ // They also return true if the object isn't owned, or the
+ // requesting agent is a system agent. See llpermissionsflags.h
+ // for bits.
+ bool allowOperationBy(PermissionBit op, const LLUUID& agent, const LLUUID& group = LLUUID::null) const;
+
+ inline bool allowModifyBy(const LLUUID &agent_id) const;
+ inline bool allowCopyBy(const LLUUID& agent_id) const;
+ inline bool allowMoveBy(const LLUUID& agent_id) const;
+ inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const;
+ inline bool allowCopyBy(const LLUUID& agent_id, const LLUUID& group) const;
+ inline bool allowMoveBy(const LLUUID &agent_id, const LLUUID &group) 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;
+
+ //
+ // DEPRECATED.
+ //
+ // These return true if the given agent can perform the function.
+ // They also return true if the object isn't owned, or the
+ // requesting agent is a system agent. See llpermissionsflags.h
+ // for bits.
+ //bool allowDeleteBy(const LLUUID& agent_id) const { return allowModifyBy(agent_id); }
+ //bool allowEditBy(const LLUUID& agent_id) const { return allowModifyBy(agent_id); }
+ // saves last owner and sets current owner
+ //bool setOwner(const LLUUID& agent, const LLUUID& owner);
+ // This method saves the last owner, sets the current owner to the
+ // one provided, and sets the base mask as indicated.
+ //bool setOwner(const LLUUID& agent, const LLUUID& owner, U32 new_base_mask);
+
+ // Attempt to set or clear the given bitmask. Returns true if you
+ // are allowed to modify the permissions. If you attempt to turn
+ // on bits not allowed by the base bits, the function will return
+ // true, but those bits will not be set.
+ //bool setGroupBits( const LLUUID& agent, bool set, PermissionMask bits);
+ //bool setEveryoneBits(const LLUUID& agent, bool set, PermissionMask bits);
+
+ //
+ // MISC METHODS and OPERATORS
+ //
+
+ LLSD packMessage() const;
+ void unpackMessage(LLSD perms);
+
+ // For messaging system support
+ void packMessage(LLMessageSystem* msg) const;
+ void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
+
+ bool importLegacyStream(std::istream& input_stream);
+ bool exportLegacyStream(std::ostream& output_stream) const;
+
+ bool operator==(const LLPermissions &rhs) const;
+ bool operator!=(const LLPermissions &rhs) const;
+
+ friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm);
+
+};
+
+// Inlines
+bool LLPermissions::allowModifyBy(const LLUUID& agent, const LLUUID& group) const
+{
+ return allowOperationBy(PERM_MODIFY, agent, group);
+}
+
+bool LLPermissions::allowCopyBy(const LLUUID& agent, const LLUUID& group) const
+{
+ return allowOperationBy(PERM_COPY, agent, group);
+}
+
+
+bool LLPermissions::allowMoveBy(const LLUUID& agent, const LLUUID& group) const
+{
+ return allowOperationBy(PERM_MOVE, agent, group);
+}
+
+bool LLPermissions::allowModifyBy(const LLUUID& agent) const
+{
+ return allowOperationBy(PERM_MODIFY, agent, LLUUID::null);
+}
+
+bool LLPermissions::allowCopyBy(const LLUUID& agent) const
+{
+ return allowOperationBy(PERM_COPY, agent, LLUUID::null);
+}
+
+bool LLPermissions::allowMoveBy(const LLUUID& agent) const
+{
+ return allowOperationBy(PERM_MOVE, agent, LLUUID::null);
+}
+
+bool LLPermissions::allowTransferTo(const LLUUID &agent_id) const
+{
+ if (mIsGroupOwned)
+ {
+ return allowOperationBy(PERM_TRANSFER, mGroup, mGroup);
+ }
+ else
+ {
+ return ((mOwner == agent_id) ? true : allowOperationBy(PERM_TRANSFER, mOwner));
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLAggregatePermissions
+//
+// Class which encapsulates object and inventory permissions,
+// ownership, etc. Currently, it only aggregates PERM_COPY,
+// PERM_MODIFY, and PERM_TRANSFER.
+//
+// Usually you will construct an instance and hand the object several
+// permissions masks to aggregate the copy, modify, and
+// transferability into a nice trinary value.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLAggregatePermissions
+{
+public:
+ enum EValue
+ {
+ AP_EMPTY = 0x00,
+ AP_NONE = 0x01,
+ AP_SOME = 0x02,
+ AP_ALL = 0x03
+ };
+
+ // construct an empty aggregate permissions
+ LLAggregatePermissions();
+
+ // pass in a PERM_COPY, PERM_TRANSFER, etc, and get out a EValue
+ // enumeration describing the current aggregate permissions.
+ EValue getValue(PermissionBit bit) const;
+
+ // returns the permissions packed into the 6 LSB of a U8:
+ // 00TTMMCC
+ // where TT = transfer, MM = modify, and CC = copy
+ // LSB is to the right
+ U8 getU8() const;
+
+ // return true is the aggregate permissions are empty, otherwise false.
+ bool isEmpty() const ;
+
+ // pass in a PERM_COPY, PERM_TRANSFER, etc, and an EValue
+ // enumeration to specifically set that value. Not implemented
+ // because I'm not sure it's a useful api.
+ //void setValue(PermissionBit bit, EValue);
+
+ // Given a mask, aggregate the useful permissions.
+ void aggregate(PermissionMask mask);
+
+ // Aggregate aggregates
+ void aggregate(const LLAggregatePermissions& ag);
+
+ // message handling
+ void packMessage(LLMessageSystem* msg, const char* field) const;
+ void unpackMessage(LLMessageSystem* msg, const char* block, const char *field, S32 block_num = 0);
+
+ static const LLAggregatePermissions empty;
+
+ friend std::ostream& operator<<(std::ostream &s, const LLAggregatePermissions &perm);
+
+protected:
+ enum EPermIndex
+ {
+ PI_COPY = 0,
+ PI_MODIFY = 1,
+ PI_TRANSFER = 2,
+ PI_END = 3,
+ PI_COUNT = 3
+ };
+ void aggregateBit(EPermIndex idx, bool allowed);
+ void aggregateIndex(EPermIndex idx, U8 bits);
+ static EPermIndex perm2PermIndex(PermissionBit bit);
+
+ // structure used to store the aggregate so far.
+ U8 mBits[PI_COUNT];
+};
+
+// These functions convert between structured data and permissions as
+// appropriate for serialization. The permissions are a map of things
+// like 'creator_id', 'owner_id', etc, with the value copied from the
+// permission object.
+LLSD ll_create_sd_from_permissions(const LLPermissions& perm);
+LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);
+
+#endif
diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h index 9ecf465c8c..aaf1fd3afb 100644 --- a/indra/llinventory/llpermissionsflags.h +++ b/indra/llinventory/llpermissionsflags.h @@ -1,24 +1,24 @@ -/** +/** * @file llpermissionsflags.h * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,47 +41,47 @@ const PermissionBit PERM_TRANSFER = (1 << 13); // 0x00002000 // objects, scale or change textures // parcels, allow building on it -const PermissionBit PERM_MODIFY = (1 << 14); // 0x00004000 +const PermissionBit PERM_MODIFY = (1 << 14); // 0x00004000 // objects, allow copy -const PermissionBit PERM_COPY = (1 << 15); // 0x00008000 +const PermissionBit PERM_COPY = (1 << 15); // 0x00008000 // parcels, allow entry, deprecated -//const PermissionBit PERM_ENTER = (1 << 16); // 0x00010000 +//const PermissionBit PERM_ENTER = (1 << 16); // 0x00010000 // parcels, allow terraform, deprecated -//const PermissionBit PERM_TERRAFORM = (1 << 17); // 0x00020000 +//const PermissionBit PERM_TERRAFORM = (1 << 17); // 0x00020000 -// NOTA BENE: This flag is NO LONGER USED!!! However, it is possible that some +// NOTA BENE: This flag is NO LONGER USED!!! However, it is possible that some // objects in the universe have it set so DON"T USE IT going forward. -//const PermissionBit PERM_OWNER_DEBIT = (1 << 18); // 0x00040000 +//const PermissionBit PERM_OWNER_DEBIT = (1 << 18); // 0x00040000 // objects, can grab/translate/rotate -const PermissionBit PERM_MOVE = (1 << 19); // 0x00080000 +const PermissionBit PERM_MOVE = (1 << 19); // 0x00080000 // parcels, avatars take damage, deprecated -//const PermissionBit PERM_DAMAGE = (1 << 20); // 0x00100000 +//const PermissionBit PERM_DAMAGE = (1 << 20); // 0x00100000 // don't use bit 31 -- printf/scanf with "%x" assume signed numbers -const PermissionBit PERM_RESERVED = ((U32)1) << 31; +const PermissionBit PERM_RESERVED = ((U32)1) << 31; -const PermissionMask PERM_NONE = 0x00000000; -const PermissionMask PERM_ALL = 0x7FFFFFFF; -//const PermissionMask PERM_ALL_PARCEL = PERM_MODIFY | PERM_ENTER | PERM_TERRAFORM | PERM_DAMAGE; +const PermissionMask PERM_NONE = 0x00000000; +const PermissionMask PERM_ALL = 0x7FFFFFFF; +//const PermissionMask PERM_ALL_PARCEL = PERM_MODIFY | PERM_ENTER | PERM_TERRAFORM | PERM_DAMAGE; const PermissionMask PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER; // Useful stuff for transmission. // Which permissions field are we trying to change? -const U8 PERM_BASE = 0x01; +const U8 PERM_BASE = 0x01; // TODO: Add another PERM_OWNER operation type for allowOperationBy DK 04/03/06 -const U8 PERM_OWNER = 0x02; -const U8 PERM_GROUP = 0x04; -const U8 PERM_EVERYONE = 0x08; +const U8 PERM_OWNER = 0x02; +const U8 PERM_GROUP = 0x04; +const U8 PERM_EVERYONE = 0x08; const U8 PERM_NEXT_OWNER = 0x10; // This is just a quickie debugging key -// no modify: PERM_ALL & ~PERM_MODIFY = 0x7fffbfff +// no modify: PERM_ALL & ~PERM_MODIFY = 0x7fffbfff // no copy: PERM_ALL & ~PERM_COPY = 0x7fff7fff // no modify or copy: = 0x7fff3fff // no transfer: PERM_ALL & ~PERM_TRANSFER = 0x7fffdfff diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 7bce5fd0cb..7bf14bc0d4 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -1,315 +1,315 @@ -/** - * @file llsaleinfo.cpp - * @brief - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <iostream> -#include "linden_common.h" - -#include "llsaleinfo.h" - -#include "llerror.h" -#include "message.h" -#include "llsdutil.h" - -// use this to avoid temporary object creation -const LLSaleInfo LLSaleInfo::DEFAULT; - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- - -const char* FOR_SALE_NAMES[] = -{ - "not", - "orig", - "copy", - "cntn" -}; - -///---------------------------------------------------------------------------- -/// Class llsaleinfo -///---------------------------------------------------------------------------- - -// Default constructor -LLSaleInfo::LLSaleInfo() : - mSaleType(LLSaleInfo::FS_NOT), - mSalePrice(DEFAULT_PRICE) -{ -} - -LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) : - mSaleType(sale_type), - mSalePrice(sale_price) -{ - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); -} - -bool LLSaleInfo::isForSale() const -{ - return (FS_NOT != mSaleType); -} - -U32 LLSaleInfo::getCRC32() const -{ - U32 rv = (U32)mSalePrice; - rv += (mSaleType * 0x07073096); - return rv; -} - -bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const -{ - output_stream << "\tsale_info\t0\n\t{\n"; - output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n"; - output_stream << "\t\tsale_price\t" << mSalePrice << "\n"; - output_stream <<"\t}\n"; - return true; -} - -LLSD LLSaleInfo::asLLSD() const -{ - LLSD sd = LLSD(); - sd["sale_type"] = lookup(mSaleType); - sd["sale_price"] = mSalePrice; - return sd; -} - -bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask) -{ - const char *w; - - if (sd["sale_type"].isString()) - { - mSaleType = lookup(sd["sale_type"].asString().c_str()); - } - else if(sd["sale_type"].isInteger()) - { - S8 type = (U8)sd["sale_type"].asInteger(); - mSaleType = static_cast<LLSaleInfo::EForSale>(type); - } - - mSalePrice = llclamp(sd["sale_price"].asInteger(), 0, S32_MAX); - w = "perm_mask"; - if (sd.has(w)) - { - has_perm_mask = true; - perm_mask = ll_U32_from_sd(sd[w]); - } - return true; -} - -bool LLSaleInfo::importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask) -{ - has_perm_mask = false; - - // *NOTE: Changing the buffer size will require changing the scanf - // calls below. - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - char keyword[MAX_STRING]; /* Flawfinder: ignore */ - char valuestr[MAX_STRING]; /* Flawfinder: ignore */ - bool success = true; - - keyword[0] = '\0'; - valuestr[0] = '\0'; - while(success && input_stream.good()) - { - input_stream.getline(buffer, MAX_STRING); - sscanf( /* Flawfinder: ignore */ - buffer, - " %254s %254s", - keyword, valuestr); - if(!keyword[0]) - { - continue; - } - if(0 == strcmp("{",keyword)) - { - continue; - } - if(0 == strcmp("}", keyword)) - { - break; - } - else if(0 == strcmp("sale_type", keyword)) - { - mSaleType = lookup(valuestr); - } - else if(0 == strcmp("sale_price", keyword)) - { - sscanf(valuestr, "%d", &mSalePrice); - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); - } - else if (!strcmp("perm_mask", keyword)) - { - //LL_INFOS() << "found deprecated keyword perm_mask" << LL_ENDL; - has_perm_mask = true; - sscanf(valuestr, "%x", &perm_mask); - } - else - { - LL_WARNS() << "unknown keyword '" << keyword - << "' in sale info import" << LL_ENDL; - } - } - return success; -} - -void LLSaleInfo::setSalePrice(S32 price) -{ - mSalePrice = price; - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); -} - -LLSD LLSaleInfo::packMessage() const -{ - LLSD result; - - U8 sale_type = static_cast<U8>(mSaleType); - result["sale-type"] = (U8)sale_type; - result["sale-price"] = (S32)mSalePrice; - //result[_PREHASH_NextOwnerMask] = mNextOwnerPermMask; - return result; -} - -void LLSaleInfo::packMessage(LLMessageSystem* msg) const -{ - U8 sale_type = static_cast<U8>(mSaleType); - msg->addU8Fast(_PREHASH_SaleType, sale_type); - msg->addS32Fast(_PREHASH_SalePrice, mSalePrice); - //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask); -} - -void LLSaleInfo::unpackMessage(LLSD sales) -{ - U8 sale_type = (U8)sales["sale-type"].asInteger(); - mSaleType = static_cast<EForSale>(sale_type); - - mSalePrice = (S32)sales["sale-price"].asInteger(); - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); - //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask); -} - -void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block) -{ - U8 sale_type; - msg->getU8Fast(block, _PREHASH_SaleType, sale_type); - mSaleType = static_cast<EForSale>(sale_type); - msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice); - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); - //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask); -} - -void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block, - S32 block_num) -{ - U8 sale_type; - msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num); - mSaleType = static_cast<EForSale>(sale_type); - msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num); - mSalePrice = llclamp(mSalePrice, 0, S32_MAX); - //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask, block_num); -} - -LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name) -{ - for(S32 i = 0; i < FS_COUNT; i++) - { - if(0 == strcmp(name, FOR_SALE_NAMES[i])) - { - // match - return (EForSale)i; - } - } - return FS_NOT; -} - -const char* LLSaleInfo::lookup(EForSale type) -{ - if((type >= 0) && (type < FS_COUNT)) - { - return FOR_SALE_NAMES[S32(type)]; - } - else - { - return NULL; - } -} - -// Allow accumulation of sale info. The price of each is added, -// conflict in sale type results in FS_NOT, and the permissions are -// tightened. -void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) -{ - if(mSaleType != sale_info.mSaleType) - { - mSaleType = FS_NOT; - } - mSalePrice += sale_info.mSalePrice; - //mNextOwnerPermMask &= sale_info.mNextOwnerPermMask; -} - -bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const -{ - return ( - (mSaleType == rhs.mSaleType) && - (mSalePrice == rhs.mSalePrice) - ); -} - -bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const -{ - return ( - (mSaleType != rhs.mSaleType) || - (mSalePrice != rhs.mSalePrice) - ); -} - - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- - -///---------------------------------------------------------------------------- -/// exported functions -///---------------------------------------------------------------------------- -static const std::string ST_TYPE_LABEL("sale_type"); -static const std::string ST_PRICE_LABEL("sale_price"); - -LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale) -{ - LLSD rv; - const char* type = LLSaleInfo::lookup(sale.getSaleType()); - if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT); - rv[ST_TYPE_LABEL] = type; - rv[ST_PRICE_LABEL] = sale.getSalePrice(); - return rv; -} - -LLSaleInfo ll_sale_info_from_sd(const LLSD& sd) -{ - LLSaleInfo rv; - rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str())); - rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX)); - return rv; -} +/**
+ * @file llsaleinfo.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <iostream>
+#include "linden_common.h"
+
+#include "llsaleinfo.h"
+
+#include "llerror.h"
+#include "message.h"
+#include "llsdutil.h"
+
+// use this to avoid temporary object creation
+const LLSaleInfo LLSaleInfo::DEFAULT;
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+const char* FOR_SALE_NAMES[] =
+{
+ "not",
+ "orig",
+ "copy",
+ "cntn"
+};
+
+///----------------------------------------------------------------------------
+/// Class llsaleinfo
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLSaleInfo::LLSaleInfo() :
+ mSaleType(LLSaleInfo::FS_NOT),
+ mSalePrice(DEFAULT_PRICE)
+{
+}
+
+LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) :
+ mSaleType(sale_type),
+ mSalePrice(sale_price)
+{
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+}
+
+bool LLSaleInfo::isForSale() const
+{
+ return (FS_NOT != mSaleType);
+}
+
+U32 LLSaleInfo::getCRC32() const
+{
+ U32 rv = (U32)mSalePrice;
+ rv += (mSaleType * 0x07073096);
+ return rv;
+}
+
+bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
+{
+ output_stream << "\tsale_info\t0\n\t{\n";
+ output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";
+ output_stream << "\t\tsale_price\t" << mSalePrice << "\n";
+ output_stream <<"\t}\n";
+ return true;
+}
+
+LLSD LLSaleInfo::asLLSD() const
+{
+ LLSD sd = LLSD();
+ sd["sale_type"] = lookup(mSaleType);
+ sd["sale_price"] = mSalePrice;
+ return sd;
+}
+
+bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask)
+{
+ const char *w;
+
+ if (sd["sale_type"].isString())
+ {
+ mSaleType = lookup(sd["sale_type"].asString().c_str());
+ }
+ else if(sd["sale_type"].isInteger())
+ {
+ S8 type = (U8)sd["sale_type"].asInteger();
+ mSaleType = static_cast<LLSaleInfo::EForSale>(type);
+ }
+
+ mSalePrice = llclamp(sd["sale_price"].asInteger(), 0, S32_MAX);
+ w = "perm_mask";
+ if (sd.has(w))
+ {
+ has_perm_mask = true;
+ perm_mask = ll_U32_from_sd(sd[w]);
+ }
+ return true;
+}
+
+bool LLSaleInfo::importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask)
+{
+ has_perm_mask = false;
+
+ // *NOTE: Changing the buffer size will require changing the scanf
+ // calls below.
+ char buffer[MAX_STRING]; /* Flawfinder: ignore */
+ char keyword[MAX_STRING]; /* Flawfinder: ignore */
+ char valuestr[MAX_STRING]; /* Flawfinder: ignore */
+ bool success = true;
+
+ keyword[0] = '\0';
+ valuestr[0] = '\0';
+ while(success && input_stream.good())
+ {
+ input_stream.getline(buffer, MAX_STRING);
+ sscanf( /* Flawfinder: ignore */
+ buffer,
+ " %254s %254s",
+ keyword, valuestr);
+ if(!keyword[0])
+ {
+ continue;
+ }
+ if(0 == strcmp("{",keyword))
+ {
+ continue;
+ }
+ if(0 == strcmp("}", keyword))
+ {
+ break;
+ }
+ else if(0 == strcmp("sale_type", keyword))
+ {
+ mSaleType = lookup(valuestr);
+ }
+ else if(0 == strcmp("sale_price", keyword))
+ {
+ sscanf(valuestr, "%d", &mSalePrice);
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+ }
+ else if (!strcmp("perm_mask", keyword))
+ {
+ //LL_INFOS() << "found deprecated keyword perm_mask" << LL_ENDL;
+ has_perm_mask = true;
+ sscanf(valuestr, "%x", &perm_mask);
+ }
+ else
+ {
+ LL_WARNS() << "unknown keyword '" << keyword
+ << "' in sale info import" << LL_ENDL;
+ }
+ }
+ return success;
+}
+
+void LLSaleInfo::setSalePrice(S32 price)
+{
+ mSalePrice = price;
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+}
+
+LLSD LLSaleInfo::packMessage() const
+{
+ LLSD result;
+
+ U8 sale_type = static_cast<U8>(mSaleType);
+ result["sale-type"] = (U8)sale_type;
+ result["sale-price"] = (S32)mSalePrice;
+ //result[_PREHASH_NextOwnerMask] = mNextOwnerPermMask;
+ return result;
+}
+
+void LLSaleInfo::packMessage(LLMessageSystem* msg) const
+{
+ U8 sale_type = static_cast<U8>(mSaleType);
+ msg->addU8Fast(_PREHASH_SaleType, sale_type);
+ msg->addS32Fast(_PREHASH_SalePrice, mSalePrice);
+ //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask);
+}
+
+void LLSaleInfo::unpackMessage(LLSD sales)
+{
+ U8 sale_type = (U8)sales["sale-type"].asInteger();
+ mSaleType = static_cast<EForSale>(sale_type);
+
+ mSalePrice = (S32)sales["sale-price"].asInteger();
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+ //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask);
+}
+
+void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
+{
+ U8 sale_type;
+ msg->getU8Fast(block, _PREHASH_SaleType, sale_type);
+ mSaleType = static_cast<EForSale>(sale_type);
+ msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice);
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+ //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask);
+}
+
+void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block,
+ S32 block_num)
+{
+ U8 sale_type;
+ msg->getU8Fast(block, _PREHASH_SaleType, sale_type, block_num);
+ mSaleType = static_cast<EForSale>(sale_type);
+ msg->getS32Fast(block, _PREHASH_SalePrice, mSalePrice, block_num);
+ mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
+ //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask, block_num);
+}
+
+LLSaleInfo::EForSale LLSaleInfo::lookup(const char* name)
+{
+ for(S32 i = 0; i < FS_COUNT; i++)
+ {
+ if(0 == strcmp(name, FOR_SALE_NAMES[i]))
+ {
+ // match
+ return (EForSale)i;
+ }
+ }
+ return FS_NOT;
+}
+
+const char* LLSaleInfo::lookup(EForSale type)
+{
+ if((type >= 0) && (type < FS_COUNT))
+ {
+ return FOR_SALE_NAMES[S32(type)];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+// Allow accumulation of sale info. The price of each is added,
+// conflict in sale type results in FS_NOT, and the permissions are
+// tightened.
+void LLSaleInfo::accumulate(const LLSaleInfo& sale_info)
+{
+ if(mSaleType != sale_info.mSaleType)
+ {
+ mSaleType = FS_NOT;
+ }
+ mSalePrice += sale_info.mSalePrice;
+ //mNextOwnerPermMask &= sale_info.mNextOwnerPermMask;
+}
+
+bool LLSaleInfo::operator==(const LLSaleInfo &rhs) const
+{
+ return (
+ (mSaleType == rhs.mSaleType) &&
+ (mSalePrice == rhs.mSalePrice)
+ );
+}
+
+bool LLSaleInfo::operator!=(const LLSaleInfo &rhs) const
+{
+ return (
+ (mSaleType != rhs.mSaleType) ||
+ (mSalePrice != rhs.mSalePrice)
+ );
+}
+
+
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+
+///----------------------------------------------------------------------------
+/// exported functions
+///----------------------------------------------------------------------------
+static const std::string ST_TYPE_LABEL("sale_type");
+static const std::string ST_PRICE_LABEL("sale_price");
+
+LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale)
+{
+ LLSD rv;
+ const char* type = LLSaleInfo::lookup(sale.getSaleType());
+ if(!type) type = LLSaleInfo::lookup(LLSaleInfo::FS_NOT);
+ rv[ST_TYPE_LABEL] = type;
+ rv[ST_PRICE_LABEL] = sale.getSalePrice();
+ return rv;
+}
+
+LLSaleInfo ll_sale_info_from_sd(const LLSD& sd)
+{
+ LLSaleInfo rv;
+ rv.setSaleType(LLSaleInfo::lookup(sd[ST_TYPE_LABEL].asString().c_str()));
+ rv.setSalePrice(llclamp((S32)sd[ST_PRICE_LABEL], 0, S32_MAX));
+ return rv;
+}
diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index b32eb6db62..ffece07f7c 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -1,120 +1,120 @@ -/** - * @file llsaleinfo.h - * @brief LLSaleInfo class header file. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLSALEINFO_H -#define LL_LLSALEINFO_H - -#include "llpermissionsflags.h" -#include "llsd.h" -#include "llxmlnode.h" - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLSaleInfo -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// L$ default price for objects -const S32 DEFAULT_PRICE = 10; - -class LLMessageSystem; - -class LLSaleInfo -{ -public: - // use this to avoid temporary object creation - static const LLSaleInfo DEFAULT; - - enum EForSale - { - // item is not to be considered for transactions - FS_NOT = 0, - - // the origional is on sale - FS_ORIGINAL = 1, - - // A copy is for sale - FS_COPY = 2, - - // Valid only for tasks, the inventory is for sale - // at the price in this structure. - FS_CONTENTS = 3, - - FS_COUNT - }; - -protected: - EForSale mSaleType; - S32 mSalePrice; - -public: - // default constructor is fine usually - LLSaleInfo(); - LLSaleInfo(EForSale sale_type, S32 sale_price); - - // accessors - bool isForSale() const; - EForSale getSaleType() const { return mSaleType; } - S32 getSalePrice() const { return mSalePrice; } - U32 getCRC32() const; - - // mutators - void setSaleType(EForSale type) { mSaleType = type; } - void setSalePrice(S32 price); - //void setNextOwnerPermMask(U32 mask) { mNextOwnerPermMask = mask; } - - bool exportLegacyStream(std::ostream& output_stream) const; - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask); - bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask); - - LLSD packMessage() const; - void unpackMessage(LLSD sales); - - // message serialization - void packMessage(LLMessageSystem* msg) const; - void unpackMessage(LLMessageSystem* msg, const char* block); - void unpackMultiMessage(LLMessageSystem* msg, const char* block, - S32 block_num); - - // static functionality for determine for sale status. - static EForSale lookup(const char* name); - static const char* lookup(EForSale type); - - // Allow accumulation of sale info. The price of each is added, - // conflict in sale type results in FS_NOT, and the permissions - // are tightened. - void accumulate(const LLSaleInfo& sale_info); - - bool operator==(const LLSaleInfo &rhs) const; - bool operator!=(const LLSaleInfo &rhs) const; -}; - -// These functions convert between structured data and sale info as -// appropriate for serialization. -LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale); -LLSaleInfo ll_sale_info_from_sd(const LLSD& sd); - -#endif // LL_LLSALEINFO_H +/**
+ * @file llsaleinfo.h
+ * @brief LLSaleInfo class header file.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSALEINFO_H
+#define LL_LLSALEINFO_H
+
+#include "llpermissionsflags.h"
+#include "llsd.h"
+#include "llxmlnode.h"
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLSaleInfo
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+// L$ default price for objects
+const S32 DEFAULT_PRICE = 10;
+
+class LLMessageSystem;
+
+class LLSaleInfo
+{
+public:
+ // use this to avoid temporary object creation
+ static const LLSaleInfo DEFAULT;
+
+ enum EForSale
+ {
+ // item is not to be considered for transactions
+ FS_NOT = 0,
+
+ // the origional is on sale
+ FS_ORIGINAL = 1,
+
+ // A copy is for sale
+ FS_COPY = 2,
+
+ // Valid only for tasks, the inventory is for sale
+ // at the price in this structure.
+ FS_CONTENTS = 3,
+
+ FS_COUNT
+ };
+
+protected:
+ EForSale mSaleType;
+ S32 mSalePrice;
+
+public:
+ // default constructor is fine usually
+ LLSaleInfo();
+ LLSaleInfo(EForSale sale_type, S32 sale_price);
+
+ // accessors
+ bool isForSale() const;
+ EForSale getSaleType() const { return mSaleType; }
+ S32 getSalePrice() const { return mSalePrice; }
+ U32 getCRC32() const;
+
+ // mutators
+ void setSaleType(EForSale type) { mSaleType = type; }
+ void setSalePrice(S32 price);
+ //void setNextOwnerPermMask(U32 mask) { mNextOwnerPermMask = mask; }
+
+ bool exportLegacyStream(std::ostream& output_stream) const;
+ LLSD asLLSD() const;
+ operator LLSD() const { return asLLSD(); }
+ bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask);
+ bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask);
+
+ LLSD packMessage() const;
+ void unpackMessage(LLSD sales);
+
+ // message serialization
+ void packMessage(LLMessageSystem* msg) const;
+ void unpackMessage(LLMessageSystem* msg, const char* block);
+ void unpackMultiMessage(LLMessageSystem* msg, const char* block,
+ S32 block_num);
+
+ // static functionality for determine for sale status.
+ static EForSale lookup(const char* name);
+ static const char* lookup(EForSale type);
+
+ // Allow accumulation of sale info. The price of each is added,
+ // conflict in sale type results in FS_NOT, and the permissions
+ // are tightened.
+ void accumulate(const LLSaleInfo& sale_info);
+
+ bool operator==(const LLSaleInfo &rhs) const;
+ bool operator!=(const LLSaleInfo &rhs) const;
+};
+
+// These functions convert between structured data and sale info as
+// appropriate for serialization.
+LLSD ll_create_sd_from_sale_info(const LLSaleInfo& sale);
+LLSaleInfo ll_sale_info_from_sd(const LLSD& sd);
+
+#endif // LL_LLSALEINFO_H
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 86340558be..c1893eff41 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -81,7 +81,7 @@ LLSettingsBase::LLSettingsBase(const LLSD setting) : } //========================================================================= -void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix) +void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix) { mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix); setDirtyFlag(true); @@ -197,7 +197,7 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c } else { - // The other or defaults does not contain this setting, keep the original value + // The other or defaults does not contain this setting, keep the original value // TODO: Should I blend this out instead? newSettings[key_name] = value; continue; @@ -253,7 +253,7 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c if (!settings.has((*it).first)) continue; - + newSettings[(*it).first] = (*it).second; } @@ -277,7 +277,7 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD switch (setting_type) { case LLSD::TypeInteger: - // lerp between the two values rounding the result to the nearest integer. + // lerp between the two values rounding the result to the nearest integer. new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix))); break; case LLSD::TypeReal: @@ -301,8 +301,8 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD new_array = q.getValue(); } else - { // TODO: We could expand this to inspect the type and do a deep lerp based on type. - // for now assume a heterogeneous array of reals. + { // TODO: We could expand this to inspect the type and do a deep lerp based on type. + // for now assume a heterogeneous array of reals. size_t len = std::max(value.size(), other_value.size()); for (size_t i = 0; i < len; ++i) @@ -364,7 +364,7 @@ LLSD LLSettingsBase::cloneSettings() const size_t LLSettingsBase::getHash() const { // get a shallow copy of the LLSD filtering out values to not include in the hash - LLSD hash_settings = llsd_shallow(getSettings(), + LLSD hash_settings = llsd_shallow(getSettings(), LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true)); boost::hash<LLSD> hasher; @@ -408,7 +408,7 @@ LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &valida LLSD errors(LLSD::emptyArray()); LLSD warnings(LLSD::emptyArray()); U32 flags(0); - + if (partial) flags |= Validator::VALIDATION_PARTIAL; @@ -517,8 +517,8 @@ bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags) if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined())) { if ((flags & VALIDATION_PARTIAL) != 0) // we are doing a partial validation. Do no attempt to set a default if missing (or fail even if required) - return true; - + return true; + if (!mDefault.isUndefined()) { data[mName] = mDefault; @@ -608,7 +608,7 @@ bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, U32, LLSD minval value[index] = minvals[index].asReal(); } } - if (maxvals[index].asString() != "*") + if (maxvals[index].asString() != "*") { if (maxvals[index].asReal() < value[index].asReal()) { diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 50276b801a..a5499c4eb6 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -48,7 +48,7 @@ #define PTR_NAMESPACE std #define SETTINGS_OVERRIDE override -class LLSettingsBase : +class LLSettingsBase : public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBase>, private boost::noncopyable { @@ -104,7 +104,7 @@ public: virtual LLSettingsType::type_e getSettingsTypeValue() const = 0; //--------------------------------------------------------------------- - // Settings status + // Settings status inline bool hasSetting(const std::string ¶m) const { return mSettings.has(param); } virtual bool isDirty() const { return mDirty; } virtual bool isVeryDirty() const { return mReplaced; } @@ -188,7 +188,7 @@ public: virtual LLSD getSettings() const; //--------------------------------------------------------------------- - // + // inline void setLLSD(const std::string &name, const LLSD &value) { mSettings[name] = value; @@ -269,7 +269,7 @@ public: { public: static const U32 VALIDATION_PARTIAL; - + typedef boost::function<bool(LLSD &, U32)> verify_pr; Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) : @@ -329,7 +329,7 @@ protected: static LLSD settingValidation(LLSD settings); typedef std::set<std::string> stringset_t; - + // combining settings objects. Customize for specific setting types virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix); @@ -342,18 +342,18 @@ protected: LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const; LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const; - /// when lerping between settings, some may require special handling. + /// when lerping between settings, some may require special handling. /// Get a list of these key to be skipped by the default settings lerp. /// (handling should be performed in the override of lerpSettings. - virtual stringset_t getSkipInterpolateKeys() const; + virtual stringset_t getSkipInterpolateKeys() const; - // A list of settings that represent quaternions and should be slerped + // A list of settings that represent quaternions and should be slerped // rather than lerped. virtual stringset_t getSlerpKeys() const { return stringset_t(); } virtual validation_list_t getValidationList() const = 0; - // Apply any settings that need special handling. + // Apply any settings that need special handling. virtual void applySpecial(void *, bool force = false) { }; virtual parammapping_t getParameterMap() const { return parammapping_t(); } @@ -362,7 +362,7 @@ protected: LLSD cloneSettings() const; - inline void setBlendFactor(BlendFactor blendfactor) + inline void setBlendFactor(BlendFactor blendfactor) { mBlendedFactor = blendfactor; } @@ -485,7 +485,7 @@ public: mLastUpdate = mTimeStart; } - virtual ~LLSettingsBlenderTimeDelta() + virtual ~LLSettingsBlenderTimeDelta() { } diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index 42dd5e3d10..ef6a187d06 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -156,7 +156,7 @@ LLSD LLSettingsDay::getSettings() const std::map<std::string, LLSettingsBase::ptr_t> in_use; LLSD tracks(LLSD::emptyArray()); - + for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack) { LLSD trackout(LLSD::emptyArray()); @@ -195,7 +195,7 @@ bool LLSettingsDay::initialize(bool validate_frames) LLSD tracks = mSettings[SETTING_TRACKS]; LLSD frames = mSettings[SETTING_FRAMES]; - // save for later... + // save for later... LLUUID assetid; if (mSettings.has(SETTING_ASSETID)) { @@ -244,7 +244,7 @@ bool LLSettingsDay::initialize(bool validate_frames) keyframe = llclamp(keyframe, 0.0f, 1.0f); LLSettingsBase::ptr_t setting; - + if ((*it).has(SETTING_KEYNAME)) { std::string key_name = (*it)[SETTING_KEYNAME]; @@ -412,7 +412,7 @@ LLSD LLSettingsDay::defaults() LLSD waterTrack; LLSD skyTrack; - + const U32 FRAME_COUNT = 8; const F32 FRAME_STEP = 1.0f / F32(FRAME_COUNT); F32 time = 0.0f; @@ -542,7 +542,7 @@ namespace { LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList(); LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky, flags); - + if (res_sky["success"].asInteger() == 0) { LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL; @@ -599,9 +599,9 @@ LLSettingsDay::validation_list_t LLSettingsDay::validationList() if (validation.empty()) { - validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray, &validateDayCycleTrack)); - validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap, + validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap, &validateDayCycleFrames)); } diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h index f7f5bb63b6..4a46eba6fe 100644 --- a/indra/llinventory/llsettingsdaycycle.h +++ b/indra/llinventory/llsettingsdaycycle.h @@ -90,7 +90,7 @@ public: //--------------------------------------------------------------------- virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); } - // Settings status + // Settings status virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE; static LLSD defaults(); @@ -128,7 +128,7 @@ public: static validation_list_t validationList(); virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); } - + LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe); LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe); diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index c3cd7262fb..3fedd61082 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -51,9 +51,9 @@ namespace { F32 cosPhi = cos(altitude); LLVector3 dir; - // +x right, +z up, +y at... + // +x right, +z up, +y at... dir.mV[0] = cosTheta * cosPhi; - dir.mV[1] = sinTheta * cosPhi; + dir.mV[1] = sinTheta * cosPhi; dir.mV[2] = sinPhi; LLVector3 axis = LLVector3::x_axis % dir; @@ -156,23 +156,23 @@ LLSettingsSky::validation_list_t legacyHazeValidationList() static LLSettingsBase::validation_list_t legacyHazeValidation; if (legacyHazeValidation.empty()) { - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray, boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f)))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f)))); - legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal, + legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 2.0f)))); legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 1000.0f)))); @@ -185,19 +185,19 @@ LLSettingsSky::validation_list_t rayleighValidationList() static LLSettingsBase::validation_list_t rayleighValidation; if (rayleighValidation.empty()) { - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return rayleighValidation; @@ -208,19 +208,19 @@ LLSettingsSky::validation_list_t absorptionValidationList() static LLSettingsBase::validation_list_t absorptionValidation; if (absorptionValidation.empty()) { - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return absorptionValidation; @@ -231,22 +231,22 @@ LLSettingsSky::validation_list_t mieValidationList() static LLSettingsBase::validation_list_t mieValidation; if (mieValidation.empty()) { - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, + + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal, + mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal, boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); } return mieValidation; @@ -296,7 +296,7 @@ bool validateRayleighLayers(LLSD &value, U32 flags) } } return allGood; - } + } llassert(value.type() == LLSD::TypeMap); LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations, flags); if (result["errors"].size() > 0) @@ -317,7 +317,7 @@ bool validateAbsorptionLayers(LLSD &value, U32 flags) LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList(); if (value.isArray()) { - bool allGood = true; + bool allGood = true; for (LLSD::array_iterator itf = value.beginArray(); itf != value.endArray(); ++itf) { LLSD& layerConfig = (*itf); @@ -447,7 +447,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mCanAutoAdjust = pother->mCanAutoAdjust; } -void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; llassert(getSettingsType() == end->getSettingsType()); @@ -533,8 +533,8 @@ LLSettingsSky::stringset_t LLSettingsSky::getSkipInterpolateKeys() const return skipSet; } -LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const -{ +LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const +{ static stringset_t slepSet; if (slepSet.empty()) @@ -561,53 +561,53 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList() validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID)); validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 1.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 3.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(1.0f, 1.0f, 1.0f, "*")))); - validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.001f, 3.0f)))); - validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(-50.0f, -50.0f), llsd::array(50.0f, 50.0f)))); - validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 2000.0f)))); - validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f)))); - validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.2f, "*", -10.0f, "*"), llsd::array(40.0f, "*", 10.0f, "*")))); - - validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, + + validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 10000.0f)))); validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0))); validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 500.0f)))); - validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, + validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray, boost::bind(&Validator::verifyVectorMinMax, _1, _2, llsd::array(0.0f, 0.0f, 0.0f, "*"), llsd::array(3.0f, 3.0f, 3.0f, "*")))); @@ -616,25 +616,25 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList() boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0))); validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID)); - validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f)))); - validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 0.1f)))); - validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); - validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(5.0f, 1000.0f)))); - validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal, + validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal, boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f)))); validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal, @@ -724,12 +724,12 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position) sunquat = convert_azimuth_and_altitude_to_quat(altitude, azimuth); moonquat = convert_azimuth_and_altitude_to_quat(altitude + (F_PI * 0.125f), azimuth + (F_PI * 0.125f)); - // Magic constants copied form dfltsetting.xml + // Magic constants copied form dfltsetting.xml dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 0.0).getValue(); dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue(); dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199); - dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.0f, 0.0f); + dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.2, 0.01); dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699); dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0); @@ -737,7 +737,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position) dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f); dfltsetting[SETTING_GAMMA] = LLSD::Real(1.0); dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue(); - + dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605); dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue(); dfltsetting[SETTING_MOON_BRIGHTNESS] = LLSD::Real(0.5f); @@ -781,7 +781,7 @@ LLSD LLSettingsSky::translateLegacyHazeSettings(const LLSD& legacy) // AdvancedAtmospherics TODO // These need to be translated into density profile info in the new settings format... -// LEGACY_ATMOSPHERICS +// LEGACY_ATMOSPHERICS if (legacy.has(SETTING_AMBIENT)) { legacyhazesettings[SETTING_AMBIENT] = LLColor3(legacy[SETTING_AMBIENT]).getValue(); @@ -871,7 +871,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy) newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(legacy[SETTING_CLOUD_SHADOW][0].asReal()); converted_something |= true; } - + if (legacy.has(SETTING_GAMMA)) { @@ -929,7 +929,7 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy) // get counter-clockwise radian angle from clockwise legacy WL east angle... F32 azimuth = -legacy[SETTING_LEGACY_EAST_ANGLE].asReal(); F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal(); - + LLQuaternion sunquat = convert_azimuth_and_altitude_to_quat(azimuth, altitude); // original WL moon dir was diametrically opposed to the sun dir LLQuaternion moonquat = convert_azimuth_and_altitude_to_quat(azimuth + F_PI, -altitude); @@ -1245,9 +1245,9 @@ LLColor3 LLSettingsSky::gammaCorrect(const LLColor3& in,const F32 &gamma) const } LLColor3 color = in * 2.0f; - color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors... - componentPow(color, gamma); - color = smear(1.f) - color; + color = smear(1.f) - componentSaturate(color); // clamping after mul seems wrong, but prevents negative colors... + componentPow(color, gamma); + color = smear(1.f) - color; return color; } @@ -1357,7 +1357,7 @@ void LLSettingsSky::calculateLightSettings() const mSunAmbient = tmpAmbient; F32 haze_horizon = getHazeHorizon(); - + sunlight *= 1.0 - cloud_shadow; sunlight += tmpAmbient; @@ -1451,7 +1451,7 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const F32 LLSettingsSky::getTotalReflectionProbeAmbiance(F32 cloud_shadow_scale, bool auto_adjust) const { #if 0 - // feed cloud shadow back into reflection probe ambiance to mimic pre-reflection-probe behavior + // feed cloud shadow back into reflection probe ambiance to mimic pre-reflection-probe behavior // without brightening dark/interior spaces F32 probe_ambiance = getReflectionProbeAmbiance(auto_adjust); @@ -1485,7 +1485,7 @@ F32 LLSettingsSky::getMieAnisotropy() const { return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal(); } - + LLSD LLSettingsSky::getRayleighConfig() const { LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray()); @@ -1503,7 +1503,7 @@ LLSD LLSettingsSky::getAbsorptionConfig() const LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray()); return copy; } - + LLSD LLSettingsSky::getRayleighConfigs() const { return mSettings[SETTING_RAYLEIGH_CONFIG]; @@ -1645,13 +1645,13 @@ void LLSettingsSky::setCloudVariance(F32 val) F32 LLSettingsSky::getDomeOffset() const { //return mSettings[SETTING_DOME_OFFSET].asReal(); - return DOME_OFFSET; + return DOME_OFFSET; } F32 LLSettingsSky::getDomeRadius() const { //return mSettings[SETTING_DOME_RADIUS].asReal(); - return DOME_RADIUS; + return DOME_RADIUS; } F32 LLSettingsSky::getGamma() const @@ -1680,7 +1680,7 @@ F32 LLSettingsSky::getMaxY() const return mSettings[SETTING_MAX_Y].asReal(); } -void LLSettingsSky::setMaxY(F32 val) +void LLSettingsSky::setMaxY(F32 val) { setValue(SETTING_MAX_Y, val); } @@ -1764,7 +1764,7 @@ LLQuaternion LLSettingsSky::getSunRotation() const return LLQuaternion(mSettings[SETTING_SUN_ROTATION]); } -void LLSettingsSky::setSunRotation(const LLQuaternion &val) +void LLSettingsSky::setSunRotation(const LLQuaternion &val) { setValue(SETTING_SUN_ROTATION, val); } @@ -1785,7 +1785,7 @@ LLUUID LLSettingsSky::getSunTextureId() const return mSettings[SETTING_SUN_TEXTUREID].asUUID(); } -void LLSettingsSky::setSunTextureId(LLUUID id) +void LLSettingsSky::setSunTextureId(LLUUID id) { setValue(SETTING_SUN_TEXTUREID, id); } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 7ba7a9ba06..8aade96484 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -62,7 +62,7 @@ public: static const std::string SETTING_DOME_OFFSET; static const std::string SETTING_DOME_RADIUS; static const std::string SETTING_GAMMA; - static const std::string SETTING_GLOW; + static const std::string SETTING_GLOW; static const std::string SETTING_LIGHT_NORMAL; static const std::string SETTING_MAX_Y; static const std::string SETTING_MOON_ROTATION; @@ -92,7 +92,7 @@ public: static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR; static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM; static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM; - + static const std::string SETTING_SKY_MOISTURE_LEVEL; static const std::string SETTING_SKY_DROPLET_RADIUS; static const std::string SETTING_SKY_ICE_LEVEL; @@ -117,7 +117,7 @@ public: virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); } virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; } - // Settings status + // Settings status virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; @@ -129,7 +129,7 @@ public: F32 getSkyBottomRadius() const; F32 getSkyTopRadius() const; F32 getSunArcRadians() const; - F32 getMieAnisotropy() const; + F32 getMieAnisotropy() const; F32 getSkyMoistureLevel() const; F32 getSkyDropletRadius() const; @@ -200,7 +200,7 @@ public: F32 getCloudShadow() const; void setCloudShadow(F32 val); - + F32 getCloudVariance() const; void setCloudVariance(F32 val); @@ -299,7 +299,7 @@ public: // color based on brightness LLColor3 getMoonlightColor() const; - + LLColor4 getMoonAmbient() const; LLColor3 getMoonDiffuse() const; LLColor4 getSunAmbient() const; diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index f5d4538c10..4cd84970ff 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -89,7 +89,7 @@ LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position) // give the normal scale offset some variability over track time... F32 normal_scale_offset = (position * 0.5f) - 0.25f; - // Magic constants copied form defaults.xml + // Magic constants copied form defaults.xml dfltsetting[SETTING_BLUR_MULTIPLIER] = LLSD::Real(0.04000f); dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue(); dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f); @@ -181,7 +181,7 @@ LLSD LLSettingsWater::translateLegacySettings(LLSD legacy) return newsettings; } -void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf) { LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end); if (other) @@ -285,7 +285,7 @@ F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const F32 fog_density = getWaterFogDensity(); F32 underwater_fog_mod = getFogMod(); if (underwater && underwater_fog_mod > 0.0f) - { + { underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f); // BUG-233797/BUG-233798 -ve underwater fog density can cause (unrecoverable) blackout. // raising a negative number to a non-integral power results in a non-real result (which is NaN for our purposes) @@ -295,7 +295,7 @@ F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const // this seems to be unlikely to be a desirable use case for the majority. // 2) Force density to be an arbitrary non-negative (i.e. 1) when underwater and modifier is not an integer (1 was aribtrarily chosen as it gives at least some notion of fog in the transition) // This is more restrictive, effectively forcing a density under certain conditions, but allowing the range of #1 and avoiding blackness in other cases - // at the cost of overriding the fog density. + // at the cost of overriding the fog density. if(fog_density < 0.0f && underwater_fog_mod != (F32)llround(underwater_fog_mod) ) { fog_density = 1.0f; diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index e0bfd29f2d..0b29d8ca19 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -61,7 +61,7 @@ public: virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); } virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; } - // Settings status + // Settings status virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; @@ -71,7 +71,7 @@ public: //--------------------------------------------------------------------- F32 getBlurMultiplier() const - { + { return mSettings[SETTING_BLUR_MULTIPLIER].asReal(); } diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp index 72e0d83d2a..a1c632f63a 100644 --- a/indra/llinventory/lltransactionflags.cpp +++ b/indra/llinventory/lltransactionflags.cpp @@ -1,168 +1,168 @@ -/** - * @file lltransactionflags.cpp - * @brief Some exported symbols and functions for dealing with - * transaction flags. - * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "lluuid.h" -#include "lltransactionflags.h" -#include "lltransactiontypes.h" - -const U8 TRANSACTION_FLAGS_NONE = 0; -const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1; -const U8 TRANSACTION_FLAG_DEST_GROUP = 2; -const U8 TRANSACTION_FLAG_OWNER_GROUP = 4; -const U8 TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION = 8; -const U8 TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION_REMOVAL = 16; - -U8 pack_transaction_flags(bool is_source_group, bool is_dest_group) -{ - U8 rv = 0; - if(is_source_group) rv |= TRANSACTION_FLAG_SOURCE_GROUP; - if(is_dest_group) rv |= TRANSACTION_FLAG_DEST_GROUP; - return rv; -} - -bool is_tf_source_group(TransactionFlags flags) -{ - return ((flags & TRANSACTION_FLAG_SOURCE_GROUP) == TRANSACTION_FLAG_SOURCE_GROUP); -} - -bool is_tf_dest_group(TransactionFlags flags) -{ - return ((flags & TRANSACTION_FLAG_DEST_GROUP) == TRANSACTION_FLAG_DEST_GROUP); -} - -bool is_tf_owner_group(TransactionFlags flags) -{ - return ((flags & TRANSACTION_FLAG_OWNER_GROUP) == TRANSACTION_FLAG_OWNER_GROUP); -} - -void append_reason( - std::ostream& ostr, - S32 transaction_type, - const std::string& description) -{ - switch( transaction_type ) - { - case TRANS_OBJECT_SALE: - ostr << " for " << (description.length() > 0 ? description : std::string("<unknown>")); - break; - case TRANS_LAND_SALE: - ostr << " for a parcel of land"; - break; - case TRANS_LAND_PASS_SALE: - ostr << " for a land access pass"; - break; - case TRANS_GROUP_LAND_DEED: - ostr << " for deeding land"; - break; - default: - break; - } -} - -std::string build_transfer_message_to_source( - S32 amount, - const LLUUID& source_id, - const LLUUID& dest_id, - const std::string& dest_name, - S32 transaction_type, - const std::string& description) -{ - LL_DEBUGS() << "build_transfer_message_to_source: " << amount << " " - << source_id << " " << dest_id << " " << dest_name << " " - << transaction_type << " " - << (description.empty() ? "(no desc)" : description) - << LL_ENDL; - if(source_id.isNull()) - { - return description; - } - if((0 == amount) && description.empty()) - { - return description; - } - std::ostringstream ostr; - if(dest_id.isNull()) - { - // *NOTE: Do not change these strings! The viewer matches - // them in llviewermessage.cpp to perform localization. - // If you need to make changes, add a new, localizable message. JC - ostr << "You paid L$" << amount; - switch(transaction_type) - { - case TRANS_GROUP_CREATE: - ostr << " to create a group"; - break; - case TRANS_GROUP_JOIN: - ostr << " to join a group"; - break; - case TRANS_UPLOAD_CHARGE: - ostr << " to upload"; - break; - default: - break; - } - } - else - { - ostr << "You paid " << dest_name << " L$" << amount; - append_reason(ostr, transaction_type, description); - } - ostr << "."; - return ostr.str(); -} - -std::string build_transfer_message_to_destination( - S32 amount, - const LLUUID& dest_id, - const LLUUID& source_id, - const std::string& source_name, - S32 transaction_type, - const std::string& description) -{ - LL_DEBUGS() << "build_transfer_message_to_dest: " << amount << " " - << dest_id << " " << source_id << " " << source_name << " " - << transaction_type << " " << (description.empty() ? "(no desc)" : description) - << LL_ENDL; - if(0 == amount) - { - return std::string(); - } - if(dest_id.isNull()) - { - return description; - } - std::ostringstream ostr; - // *NOTE: Do not change these strings! The viewer matches - // them in llviewermessage.cpp to perform localization. - // If you need to make changes, add a new, localizable message. JC - ostr << source_name << " paid you L$" << amount; - append_reason(ostr, transaction_type, description); - ostr << "."; - return ostr.str(); -} +/**
+ * @file lltransactionflags.cpp
+ * @brief Some exported symbols and functions for dealing with
+ * transaction flags.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lluuid.h"
+#include "lltransactionflags.h"
+#include "lltransactiontypes.h"
+
+const U8 TRANSACTION_FLAGS_NONE = 0;
+const U8 TRANSACTION_FLAG_SOURCE_GROUP = 1;
+const U8 TRANSACTION_FLAG_DEST_GROUP = 2;
+const U8 TRANSACTION_FLAG_OWNER_GROUP = 4;
+const U8 TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION = 8;
+const U8 TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION_REMOVAL = 16;
+
+U8 pack_transaction_flags(bool is_source_group, bool is_dest_group)
+{
+ U8 rv = 0;
+ if(is_source_group) rv |= TRANSACTION_FLAG_SOURCE_GROUP;
+ if(is_dest_group) rv |= TRANSACTION_FLAG_DEST_GROUP;
+ return rv;
+}
+
+bool is_tf_source_group(TransactionFlags flags)
+{
+ return ((flags & TRANSACTION_FLAG_SOURCE_GROUP) == TRANSACTION_FLAG_SOURCE_GROUP);
+}
+
+bool is_tf_dest_group(TransactionFlags flags)
+{
+ return ((flags & TRANSACTION_FLAG_DEST_GROUP) == TRANSACTION_FLAG_DEST_GROUP);
+}
+
+bool is_tf_owner_group(TransactionFlags flags)
+{
+ return ((flags & TRANSACTION_FLAG_OWNER_GROUP) == TRANSACTION_FLAG_OWNER_GROUP);
+}
+
+void append_reason(
+ std::ostream& ostr,
+ S32 transaction_type,
+ const std::string& description)
+{
+ switch( transaction_type )
+ {
+ case TRANS_OBJECT_SALE:
+ ostr << " for " << (description.length() > 0 ? description : std::string("<unknown>"));
+ break;
+ case TRANS_LAND_SALE:
+ ostr << " for a parcel of land";
+ break;
+ case TRANS_LAND_PASS_SALE:
+ ostr << " for a land access pass";
+ break;
+ case TRANS_GROUP_LAND_DEED:
+ ostr << " for deeding land";
+ break;
+ default:
+ break;
+ }
+}
+
+std::string build_transfer_message_to_source(
+ S32 amount,
+ const LLUUID& source_id,
+ const LLUUID& dest_id,
+ const std::string& dest_name,
+ S32 transaction_type,
+ const std::string& description)
+{
+ LL_DEBUGS() << "build_transfer_message_to_source: " << amount << " "
+ << source_id << " " << dest_id << " " << dest_name << " "
+ << transaction_type << " "
+ << (description.empty() ? "(no desc)" : description)
+ << LL_ENDL;
+ if(source_id.isNull())
+ {
+ return description;
+ }
+ if((0 == amount) && description.empty())
+ {
+ return description;
+ }
+ std::ostringstream ostr;
+ if(dest_id.isNull())
+ {
+ // *NOTE: Do not change these strings! The viewer matches
+ // them in llviewermessage.cpp to perform localization.
+ // If you need to make changes, add a new, localizable message. JC
+ ostr << "You paid L$" << amount;
+ switch(transaction_type)
+ {
+ case TRANS_GROUP_CREATE:
+ ostr << " to create a group";
+ break;
+ case TRANS_GROUP_JOIN:
+ ostr << " to join a group";
+ break;
+ case TRANS_UPLOAD_CHARGE:
+ ostr << " to upload";
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ ostr << "You paid " << dest_name << " L$" << amount;
+ append_reason(ostr, transaction_type, description);
+ }
+ ostr << ".";
+ return ostr.str();
+}
+
+std::string build_transfer_message_to_destination(
+ S32 amount,
+ const LLUUID& dest_id,
+ const LLUUID& source_id,
+ const std::string& source_name,
+ S32 transaction_type,
+ const std::string& description)
+{
+ LL_DEBUGS() << "build_transfer_message_to_dest: " << amount << " "
+ << dest_id << " " << source_id << " " << source_name << " "
+ << transaction_type << " " << (description.empty() ? "(no desc)" : description)
+ << LL_ENDL;
+ if(0 == amount)
+ {
+ return std::string();
+ }
+ if(dest_id.isNull())
+ {
+ return description;
+ }
+ std::ostringstream ostr;
+ // *NOTE: Do not change these strings! The viewer matches
+ // them in llviewermessage.cpp to perform localization.
+ // If you need to make changes, add a new, localizable message. JC
+ ostr << source_name << " paid you L$" << amount;
+ append_reason(ostr, transaction_type, description);
+ ostr << ".";
+ return ostr.str();
+}
diff --git a/indra/llinventory/lltransactionflags.h b/indra/llinventory/lltransactionflags.h index ca426035b4..c20adbebb2 100644 --- a/indra/llinventory/lltransactionflags.h +++ b/indra/llinventory/lltransactionflags.h @@ -1,65 +1,65 @@ -/** - * @file lltransactionflags.h - * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLTRANSACTIONFLAGS_H -#define LL_LLTRANSACTIONFLAGS_H - -class LLUUID; - -typedef U8 TransactionFlags; - -// defined in common/llinventory/lltransactionflags.cpp -extern const TransactionFlags TRANSACTION_FLAGS_NONE; -extern const TransactionFlags TRANSACTION_FLAG_SOURCE_GROUP; -extern const TransactionFlags TRANSACTION_FLAG_DEST_GROUP; -extern const TransactionFlags TRANSACTION_FLAG_OWNER_GROUP; -extern const TransactionFlags TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION; -extern const TransactionFlags TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION_REMOVAL; - -// very simple helper functions -TransactionFlags pack_transaction_flags(bool is_source_group, bool is_dest_group); -bool is_tf_source_group(TransactionFlags flags); -bool is_tf_dest_group(TransactionFlags flags); -bool is_tf_owner_group(TransactionFlags flags); - -// stupid helper functions which should be replaced with some kind of -// internationalizeable message. -std::string build_transfer_message_to_source( - S32 amount, - const LLUUID& source_id, - const LLUUID& dest_id, - const std::string& dest_name, - S32 transaction_type, - const std::string& description); - -std::string build_transfer_message_to_destination( - S32 amount, - const LLUUID& dest_id, - const LLUUID& source_id, - const std::string& source_name, - S32 transaction_type, - const std::string& description); - -#endif // LL_LLTRANSACTIONFLAGS_H +/**
+ * @file lltransactionflags.h
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTRANSACTIONFLAGS_H
+#define LL_LLTRANSACTIONFLAGS_H
+
+class LLUUID;
+
+typedef U8 TransactionFlags;
+
+// defined in common/llinventory/lltransactionflags.cpp
+extern const TransactionFlags TRANSACTION_FLAGS_NONE;
+extern const TransactionFlags TRANSACTION_FLAG_SOURCE_GROUP;
+extern const TransactionFlags TRANSACTION_FLAG_DEST_GROUP;
+extern const TransactionFlags TRANSACTION_FLAG_OWNER_GROUP;
+extern const TransactionFlags TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION;
+extern const TransactionFlags TRANSACTION_FLAG_SIMULTANEOUS_CONTRIBUTION_REMOVAL;
+
+// very simple helper functions
+TransactionFlags pack_transaction_flags(bool is_source_group, bool is_dest_group);
+bool is_tf_source_group(TransactionFlags flags);
+bool is_tf_dest_group(TransactionFlags flags);
+bool is_tf_owner_group(TransactionFlags flags);
+
+// stupid helper functions which should be replaced with some kind of
+// internationalizeable message.
+std::string build_transfer_message_to_source(
+ S32 amount,
+ const LLUUID& source_id,
+ const LLUUID& dest_id,
+ const std::string& dest_name,
+ S32 transaction_type,
+ const std::string& description);
+
+std::string build_transfer_message_to_destination(
+ S32 amount,
+ const LLUUID& dest_id,
+ const LLUUID& source_id,
+ const std::string& source_name,
+ S32 transaction_type,
+ const std::string& description);
+
+#endif // LL_LLTRANSACTIONFLAGS_H
diff --git a/indra/llinventory/lltransactiontypes.h b/indra/llinventory/lltransactiontypes.h index 6f8d005f1b..3732ad62fb 100644 --- a/indra/llinventory/lltransactiontypes.h +++ b/indra/llinventory/lltransactiontypes.h @@ -1,24 +1,24 @@ -/** +/** * @file lltransactiontypes.h * * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -30,38 +30,38 @@ // transaction_description table in the database. If you add a // constant here, please add it to the database. eg: // -// insert into transaction_description +// insert into transaction_description // set type = 1000, description = 'Object Claim'; // // Also add it to the various L$ string lookups on the dataserver // in lldatamoney // Money transaction failure codes -const U8 TRANS_FAIL_SIMULATOR_TIMEOUT = 1; -const U8 TRANS_FAIL_DATASERVER_TIMEOUT = 2; +const U8 TRANS_FAIL_SIMULATOR_TIMEOUT = 1; +const U8 TRANS_FAIL_DATASERVER_TIMEOUT = 2; const U8 TRANS_FAIL_APPLICATION = 3; // Codes up to 999 for error conditions -const S32 TRANS_NULL = 0; +const S32 TRANS_NULL = 0; // Codes 1000-1999 reserved for one-time charges -const S32 TRANS_OBJECT_CLAIM = 1000; -const S32 TRANS_LAND_CLAIM = 1001; -const S32 TRANS_GROUP_CREATE = 1002; -const S32 TRANS_OBJECT_PUBLIC_CLAIM = 1003; -const S32 TRANS_GROUP_JOIN = 1004; // May be moved to group transactions eventually -const S32 TRANS_TELEPORT_CHARGE = 1100; // FF not sure why this jumps to 1100... -const S32 TRANS_UPLOAD_CHARGE = 1101; -const S32 TRANS_LAND_AUCTION = 1102; -const S32 TRANS_CLASSIFIED_CHARGE = 1103; +const S32 TRANS_OBJECT_CLAIM = 1000; +const S32 TRANS_LAND_CLAIM = 1001; +const S32 TRANS_GROUP_CREATE = 1002; +const S32 TRANS_OBJECT_PUBLIC_CLAIM = 1003; +const S32 TRANS_GROUP_JOIN = 1004; // May be moved to group transactions eventually +const S32 TRANS_TELEPORT_CHARGE = 1100; // FF not sure why this jumps to 1100... +const S32 TRANS_UPLOAD_CHARGE = 1101; +const S32 TRANS_LAND_AUCTION = 1102; +const S32 TRANS_CLASSIFIED_CHARGE = 1103; // Codes 2000-2999 reserved for recurrent charges -const S32 TRANS_OBJECT_TAX = 2000; -const S32 TRANS_LAND_TAX = 2001; -const S32 TRANS_LIGHT_TAX = 2002; -const S32 TRANS_PARCEL_DIR_FEE = 2003; -const S32 TRANS_GROUP_TAX = 2004; // Taxes incurred as part of group membership -const S32 TRANS_CLASSIFIED_RENEW = 2005; +const S32 TRANS_OBJECT_TAX = 2000; +const S32 TRANS_LAND_TAX = 2001; +const S32 TRANS_LIGHT_TAX = 2002; +const S32 TRANS_PARCEL_DIR_FEE = 2003; +const S32 TRANS_GROUP_TAX = 2004; // Taxes incurred as part of group membership +const S32 TRANS_CLASSIFIED_RENEW = 2005; // Codes 2100-2999 reserved for recurring billing services // New codes can be created through an admin interface so may not @@ -70,19 +70,19 @@ const S32 TRANS_CLASSIFIED_RENEW = 2005; const S32 TRANS_RECURRING_GENERIC = 2100; // Codes 3000-3999 reserved for inventory transactions -const S32 TRANS_GIVE_INVENTORY = 3000; +const S32 TRANS_GIVE_INVENTORY = 3000; // Codes 5000-5999 reserved for transfers between users -const S32 TRANS_OBJECT_SALE = 5000; -const S32 TRANS_GIFT = 5001; -const S32 TRANS_LAND_SALE = 5002; -const S32 TRANS_REFER_BONUS = 5003; -const S32 TRANS_INVENTORY_SALE = 5004; -const S32 TRANS_REFUND_PURCHASE = 5005; -const S32 TRANS_LAND_PASS_SALE = 5006; -const S32 TRANS_DWELL_BONUS = 5007; -const S32 TRANS_PAY_OBJECT = 5008; -const S32 TRANS_OBJECT_PAYS = 5009; +const S32 TRANS_OBJECT_SALE = 5000; +const S32 TRANS_GIFT = 5001; +const S32 TRANS_LAND_SALE = 5002; +const S32 TRANS_REFER_BONUS = 5003; +const S32 TRANS_INVENTORY_SALE = 5004; +const S32 TRANS_REFUND_PURCHASE = 5005; +const S32 TRANS_LAND_PASS_SALE = 5006; +const S32 TRANS_DWELL_BONUS = 5007; +const S32 TRANS_PAY_OBJECT = 5008; +const S32 TRANS_OBJECT_PAYS = 5009; // Codes 5100-5999 reserved for recurring billing transfers between users // New codes can be created through an admin interface so may not @@ -91,34 +91,34 @@ const S32 TRANS_OBJECT_PAYS = 5009; const S32 TRANS_RECURRING_GENERIC_USER = 5100; // Codes 6000-6999 reserved for group transactions -//const S32 TRANS_GROUP_JOIN = 6000; //reserved for future use -const S32 TRANS_GROUP_LAND_DEED = 6001; -const S32 TRANS_GROUP_OBJECT_DEED = 6002; -const S32 TRANS_GROUP_LIABILITY = 6003; -const S32 TRANS_GROUP_DIVIDEND = 6004; -const S32 TRANS_MEMBERSHIP_DUES = 6005; +//const S32 TRANS_GROUP_JOIN = 6000; //reserved for future use +const S32 TRANS_GROUP_LAND_DEED = 6001; +const S32 TRANS_GROUP_OBJECT_DEED = 6002; +const S32 TRANS_GROUP_LIABILITY = 6003; +const S32 TRANS_GROUP_DIVIDEND = 6004; +const S32 TRANS_MEMBERSHIP_DUES = 6005; // Codes 8000-8999 reserved for one-type credits -const S32 TRANS_OBJECT_RELEASE = 8000; -const S32 TRANS_LAND_RELEASE = 8001; -const S32 TRANS_OBJECT_DELETE = 8002; -const S32 TRANS_OBJECT_PUBLIC_DECAY = 8003; +const S32 TRANS_OBJECT_RELEASE = 8000; +const S32 TRANS_LAND_RELEASE = 8001; +const S32 TRANS_OBJECT_DELETE = 8002; +const S32 TRANS_OBJECT_PUBLIC_DECAY = 8003; const S32 TRANS_OBJECT_PUBLIC_DELETE= 8004; // Code 9000-9099 reserved for usertool transactions -const S32 TRANS_LINDEN_ADJUSTMENT = 9000; -const S32 TRANS_LINDEN_GRANT = 9001; -const S32 TRANS_LINDEN_PENALTY = 9002; -const S32 TRANS_EVENT_FEE = 9003; -const S32 TRANS_EVENT_PRIZE = 9004; +const S32 TRANS_LINDEN_ADJUSTMENT = 9000; +const S32 TRANS_LINDEN_GRANT = 9001; +const S32 TRANS_LINDEN_PENALTY = 9002; +const S32 TRANS_EVENT_FEE = 9003; +const S32 TRANS_EVENT_PRIZE = 9004; // These must match entries in money_stipend table in MySQL // Codes 10000-10999 reserved for stipend credits -const S32 TRANS_STIPEND_BASIC = 10000; -const S32 TRANS_STIPEND_DEVELOPER = 10001; -const S32 TRANS_STIPEND_ALWAYS = 10002; -const S32 TRANS_STIPEND_DAILY = 10003; -const S32 TRANS_STIPEND_RATING = 10004; +const S32 TRANS_STIPEND_BASIC = 10000; +const S32 TRANS_STIPEND_DEVELOPER = 10001; +const S32 TRANS_STIPEND_ALWAYS = 10002; +const S32 TRANS_STIPEND_DAILY = 10003; +const S32 TRANS_STIPEND_RATING = 10004; const S32 TRANS_STIPEND_DELTA = 10005; #endif diff --git a/indra/llinventory/lluserrelations.cpp b/indra/llinventory/lluserrelations.cpp index b938dfeb7b..1abeec0700 100644 --- a/indra/llinventory/lluserrelations.cpp +++ b/indra/llinventory/lluserrelations.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lluserrelations.cpp * @author Phoenix * @date 2006-10-12 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,79 +34,79 @@ const U8 LLRelationship::GRANTED_VISIBLE_MASK = LLRelationship::GRANT_MODIFY_OBJ const LLRelationship LLRelationship::DEFAULT_RELATIONSHIP = LLRelationship(GRANT_ONLINE_STATUS, GRANT_ONLINE_STATUS, false); LLRelationship::LLRelationship() : - mGrantToAgent(0), - mGrantFromAgent(0), - mChangeSerialNum(0), - mIsOnline(false) + mGrantToAgent(0), + mGrantFromAgent(0), + mChangeSerialNum(0), + mIsOnline(false) { } LLRelationship::LLRelationship(S32 grant_to, S32 grant_from, bool is_online) : - mGrantToAgent(grant_to), - mGrantFromAgent(grant_from), - mChangeSerialNum(0), - mIsOnline(is_online) + mGrantToAgent(grant_to), + mGrantFromAgent(grant_from), + mChangeSerialNum(0), + mIsOnline(is_online) { } bool LLRelationship::isOnline() const { - return mIsOnline; + return mIsOnline; } void LLRelationship::online(bool is_online) { - mIsOnline = is_online; - mChangeSerialNum++; + mIsOnline = is_online; + mChangeSerialNum++; } bool LLRelationship::isRightGrantedTo(S32 rights) const { - return ((mGrantToAgent & rights) == rights); + return ((mGrantToAgent & rights) == rights); } bool LLRelationship::isRightGrantedFrom(S32 rights) const { - return ((mGrantFromAgent & rights) == rights); + return ((mGrantFromAgent & rights) == rights); } S32 LLRelationship::getRightsGrantedTo() const { - return mGrantToAgent; + return mGrantToAgent; } S32 LLRelationship::getRightsGrantedFrom() const { - return mGrantFromAgent; + return mGrantFromAgent; } void LLRelationship::grantRights(S32 to_agent, S32 from_agent) { - mGrantToAgent |= to_agent; - mGrantFromAgent |= from_agent; - mChangeSerialNum++; + mGrantToAgent |= to_agent; + mGrantFromAgent |= from_agent; + mChangeSerialNum++; } void LLRelationship::revokeRights(S32 to_agent, S32 from_agent) { - mGrantToAgent &= ~to_agent; - mGrantFromAgent &= ~from_agent; - mChangeSerialNum++; + mGrantToAgent &= ~to_agent; + mGrantFromAgent &= ~from_agent; + mChangeSerialNum++; } /* bool LLGrantedRights::getNextRights( - LLUUID& agent_id, - S32& to_agent, - S32& from_agent) const + LLUUID& agent_id, + S32& to_agent, + S32& from_agent) const { - rights_map_t::const_iterator iter = mRights.upper_bound(agent_id); - if(iter == mRights.end()) return false; - agent_id = (*iter).first; - to_agent = (*iter).second.mToAgent; - from_agent = (*iter).second.mFromAgent; - return true; + rights_map_t::const_iterator iter = mRights.upper_bound(agent_id); + if(iter == mRights.end()) return false; + agent_id = (*iter).first; + to_agent = (*iter).second.mToAgent; + from_agent = (*iter).second.mFromAgent; + return true; } */ diff --git a/indra/llinventory/lluserrelations.h b/indra/llinventory/lluserrelations.h index 9fbf36f0e2..3ca6f36145 100644 --- a/indra/llinventory/lluserrelations.h +++ b/indra/llinventory/lluserrelations.h @@ -1,4 +1,4 @@ -/** +/** * @file lluserrelations.h * @author Phoenix * @date 2006-10-12 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,13 +32,13 @@ #include <map> #include "lluuid.h" -/** +/** * @class LLRelationship * * This class represents a relationship between two agents, where the * related agent is stored and the other agent is the relationship is * implicit by container ownership. - * This is merely a cache of this information used by the sim + * This is merely a cache of this information used by the sim * and viewer. * * You are expected to use this in a map or similar structure, eg: @@ -47,137 +47,137 @@ class LLRelationship { public: - /** - * @brief Constructors. - */ - LLRelationship(); - LLRelationship(S32 grant_to, S32 grant_from, bool is_online); - - static const LLRelationship DEFAULT_RELATIONSHIP; - - /** - * @name Status functionality - * - * I thought it would be keen to have a generic status interface, - * but the only thing we currently cache is online status. As this - * assumption changes, this API may evolve. - */ - //@{ - /** - * @brief Does this instance believe the related agent is currently - * online or available. - * - * NOTE: This API may be deprecated if there is any transient status - * other than online status, for example, away/busy/etc. - * - * This call does not check any kind of central store or make any - * deep information calls - it simply checks a cache of online - * status. - * @return Returns true if this relationship believes the agent is - * online. - */ - bool isOnline() const; - - /** - * @brief Set the online status. - * - * NOTE: This API may be deprecated if there is any transient status - * other than online status. - * @param is_online Se the online status - */ - void online(bool is_online); - //@} - - /* @name Granted rights - */ - //@{ - /** - * @brief Anonymous enumeration for specifying rights. - */ - enum - { - GRANT_NONE = 0x0, - GRANT_ONLINE_STATUS = 0x1, - GRANT_MAP_LOCATION = 0x2, - GRANT_MODIFY_OBJECTS = 0x4, - }; - - /** - * ??? - */ - static const U8 GRANTED_VISIBLE_MASK; - - /** - * @brief Check for a set of rights granted to agent. - * - * @param rights A bitfield to check for rights. - * @return Returns true if all rights have been granted. - */ - bool isRightGrantedTo(S32 rights) const; - - /** - * @brief Check for a set of rights granted from an agent. - * - * @param rights A bitfield to check for rights. - * @return Returns true if all rights have been granted. - */ - bool isRightGrantedFrom(S32 rights) const; - - /** - * @brief Get the rights granted to the other agent. - * - * @return Returns the bitmask of granted rights. - */ - S32 getRightsGrantedTo() const; - - /** - * @brief Get the rights granted from the other agent. - * - * @return Returns the bitmask of granted rights. - */ - S32 getRightsGrantedFrom() const; - - void setRightsTo(S32 to_agent) { mGrantToAgent = to_agent; mChangeSerialNum++; } - void setRightsFrom(S32 from_agent) { mGrantFromAgent = from_agent; mChangeSerialNum++;} - - /** - * @brief Get the change count for this agent - * - * Every change to rights will increment the serial number - * allowing listeners to determine when a relationship value is actually new - * - * @return change serial number for relationship - */ - S32 getChangeSerialNum() const { return mChangeSerialNum; } - - /** - * @brief Grant a set of rights. - * - * Any bit which is set will grant that right if it is set in the - * instance. You can pass in LLGrantedRights::NONE to not change - * that field. - * @param to_agent The rights to grant to agent_id. - * @param from_agent The rights granted from agent_id. - */ - void grantRights(S32 to_agent, S32 from_agent); - - /** - * @brief Revoke a set of rights. - * - * Any bit which is set will revoke that right if it is set in the - * instance. You can pass in LLGrantedRights::NONE to not change - * that field. - * @param to_agent The rights to grant to agent_id. - * @param from_agent The rights granted from agent_id. - */ - void revokeRights(S32 to_agent, S32 from_agent); - //@} + /** + * @brief Constructors. + */ + LLRelationship(); + LLRelationship(S32 grant_to, S32 grant_from, bool is_online); + + static const LLRelationship DEFAULT_RELATIONSHIP; + + /** + * @name Status functionality + * + * I thought it would be keen to have a generic status interface, + * but the only thing we currently cache is online status. As this + * assumption changes, this API may evolve. + */ + //@{ + /** + * @brief Does this instance believe the related agent is currently + * online or available. + * + * NOTE: This API may be deprecated if there is any transient status + * other than online status, for example, away/busy/etc. + * + * This call does not check any kind of central store or make any + * deep information calls - it simply checks a cache of online + * status. + * @return Returns true if this relationship believes the agent is + * online. + */ + bool isOnline() const; + + /** + * @brief Set the online status. + * + * NOTE: This API may be deprecated if there is any transient status + * other than online status. + * @param is_online Se the online status + */ + void online(bool is_online); + //@} + + /* @name Granted rights + */ + //@{ + /** + * @brief Anonymous enumeration for specifying rights. + */ + enum + { + GRANT_NONE = 0x0, + GRANT_ONLINE_STATUS = 0x1, + GRANT_MAP_LOCATION = 0x2, + GRANT_MODIFY_OBJECTS = 0x4, + }; + + /** + * ??? + */ + static const U8 GRANTED_VISIBLE_MASK; + + /** + * @brief Check for a set of rights granted to agent. + * + * @param rights A bitfield to check for rights. + * @return Returns true if all rights have been granted. + */ + bool isRightGrantedTo(S32 rights) const; + + /** + * @brief Check for a set of rights granted from an agent. + * + * @param rights A bitfield to check for rights. + * @return Returns true if all rights have been granted. + */ + bool isRightGrantedFrom(S32 rights) const; + + /** + * @brief Get the rights granted to the other agent. + * + * @return Returns the bitmask of granted rights. + */ + S32 getRightsGrantedTo() const; + + /** + * @brief Get the rights granted from the other agent. + * + * @return Returns the bitmask of granted rights. + */ + S32 getRightsGrantedFrom() const; + + void setRightsTo(S32 to_agent) { mGrantToAgent = to_agent; mChangeSerialNum++; } + void setRightsFrom(S32 from_agent) { mGrantFromAgent = from_agent; mChangeSerialNum++;} + + /** + * @brief Get the change count for this agent + * + * Every change to rights will increment the serial number + * allowing listeners to determine when a relationship value is actually new + * + * @return change serial number for relationship + */ + S32 getChangeSerialNum() const { return mChangeSerialNum; } + + /** + * @brief Grant a set of rights. + * + * Any bit which is set will grant that right if it is set in the + * instance. You can pass in LLGrantedRights::NONE to not change + * that field. + * @param to_agent The rights to grant to agent_id. + * @param from_agent The rights granted from agent_id. + */ + void grantRights(S32 to_agent, S32 from_agent); + + /** + * @brief Revoke a set of rights. + * + * Any bit which is set will revoke that right if it is set in the + * instance. You can pass in LLGrantedRights::NONE to not change + * that field. + * @param to_agent The rights to grant to agent_id. + * @param from_agent The rights granted from agent_id. + */ + void revokeRights(S32 to_agent, S32 from_agent); + //@} protected: - S32 mGrantToAgent; - S32 mGrantFromAgent; - S32 mChangeSerialNum; - bool mIsOnline; + S32 mGrantToAgent; + S32 mGrantFromAgent; + S32 mChangeSerialNum; + bool mIsOnline; }; #endif // LL_LLUSERRELAIONS_H diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp index 0f38dd9104..e1eb3d89ea 100644 --- a/indra/llinventory/tests/inventorymisc_test.cpp +++ b/indra/llinventory/tests/inventorymisc_test.cpp @@ -1,512 +1,512 @@ -/** - * @file inventory.cpp - * @author Phoenix - * @date 2005-11-15 - * @brief Functions for inventory test framework - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llsd.h" -#include "llsdserialize.h" - -#include "../llinventory.h" -#include "../test/lltut.h" - - -#if LL_WINDOWS -// disable unreachable code warnings -#pragma warning(disable: 4702) -#endif - -LLPointer<LLInventoryItem> create_random_inventory_item() -{ - LLUUID item_id; - item_id.generate(); - LLUUID parent_id; - parent_id.generate(); - LLPermissions perm; - LLUUID creator_id; - creator_id.generate(); - LLUUID owner_id; - owner_id.generate(); - LLUUID last_owner_id; - last_owner_id.generate(); - LLUUID group_id; - group_id.generate(); - perm.init(creator_id, owner_id, last_owner_id, group_id); - perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); - LLUUID asset_id; - asset_id.generate(); - S32 price = rand(); - LLSaleInfo sale_info(LLSaleInfo::FS_COPY, price); - U32 flags = rand(); - S32 creation = time(NULL); - - LLPointer<LLInventoryItem> item = new LLInventoryItem( - item_id, - parent_id, - perm, - asset_id, - LLAssetType::AT_OBJECT, - LLInventoryType::IT_ATTACHMENT, - std::string("Sample Object"), - std::string("Used for Testing"), - sale_info, - flags, - creation); - return item; -} - -LLPointer<LLInventoryCategory> create_random_inventory_cat() -{ - LLUUID item_id; - item_id.generate(); - LLUUID parent_id; - parent_id.generate(); - - LLPointer<LLInventoryCategory> cat = new LLInventoryCategory( - item_id, - parent_id, - LLFolderType::FT_NONE, - std::string("Sample category")); - return cat; -} - -namespace tut -{ - struct inventory_data - { - }; - typedef test_group<inventory_data> inventory_test; - typedef inventory_test::object inventory_object; - tut::inventory_test inv("LLInventory"); - -//***class LLInventoryType***// - - - template<> template<> - void inventory_object::test<1>() - { - LLInventoryType::EType retType = LLInventoryType::lookup(std::string("sound")); - ensure("1.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SOUND); - - retType = LLInventoryType::lookup(std::string("snapshot")); - ensure("2.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SNAPSHOT); - } - - template<> template<> - void inventory_object::test<2>() - { - static std::string retType = LLInventoryType::lookup(LLInventoryType::IT_CALLINGCARD); - ensure("1.LLInventoryType::lookup(EType) failed", (retType == "callcard")); - - retType = LLInventoryType::lookup(LLInventoryType::IT_LANDMARK); - ensure("2.LLInventoryType::lookup(EType) failed", (retType == "landmark")); - - } - - template<> template<> - void inventory_object::test<3>() - { - static std::string retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_CALLINGCARD); - ensure("1.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "calling card")); - - retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_LANDMARK); - ensure("2.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "landmark")); - } - - template<> template<> - void inventory_object::test<4>() - { - static LLInventoryType::EType retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE); - ensure("1.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_TEXTURE); - - retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_LANDMARK); - ensure("2.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_LANDMARK); - } - -//*****class LLInventoryItem*****// - - template<> template<> - void inventory_object::test<5>() - { - LLPointer<LLInventoryItem> src = create_random_inventory_item(); - LLSD sd = ll_create_sd_from_inventory_item(src); - //LL_INFOS() << "sd: " << *sd << LL_ENDL; - LLPointer<LLInventoryItem> dst = new LLInventoryItem; - bool successful_parse = dst->fromLLSD(sd); - ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true); - ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); - ensure_equals("3.name::getName() failed", dst->getName(), src->getName()); - ensure_equals("4.type::getType() failed", dst->getType(), src->getType()); - - ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions()); - ensure_equals("6.description::getDescription() failed", dst->getDescription(), src->getDescription()); - ensure_equals("7.sale type::getSaleType() failed", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType()); - ensure_equals("8.sale price::getSalePrice() failed", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice()); - ensure_equals("9.asset id::getAssetUUID() failed", dst->getAssetUUID(), src->getAssetUUID()); - ensure_equals("10.inventory type::getInventoryType() failed", dst->getInventoryType(), src->getInventoryType()); - ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src->getFlags()); - ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate()); - - LLUUID new_item_id, new_parent_id; - new_item_id.generate(); - src->setUUID(new_item_id); - - new_parent_id.generate(); - src->setParent(new_parent_id); - - std::string new_name = "LindenLab"; - src->rename(new_name); - - src->setType(LLAssetType::AT_SOUND); - - LLUUID new_asset_id; - new_asset_id.generate(); - - src->setAssetUUID(new_asset_id); - std::string new_desc = "SecondLife Testing"; - src->setDescription(new_desc); - - S32 new_price = rand(); - LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price); - src->setSaleInfo(new_sale_info); - - U32 new_flags = rand(); - S32 new_creation = time(NULL); - - LLPermissions new_perm; - - LLUUID new_creator_id; - new_creator_id.generate(); - - LLUUID new_owner_id; - new_owner_id.generate(); - - LLUUID last_owner_id; - last_owner_id.generate(); - - LLUUID new_group_id; - new_group_id.generate(); - new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id); - new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); - src->setPermissions(new_perm); - - src->setInventoryType(LLInventoryType::IT_SOUND); - src->setFlags(new_flags); - src->setCreationDate(new_creation); - - sd = ll_create_sd_from_inventory_item(src); - //LL_INFOS() << "sd: " << *sd << LL_ENDL; - successful_parse = dst->fromLLSD(sd); - ensure_equals("13.item id::getUUID() failed", dst->getUUID(), src->getUUID()); - ensure_equals("14.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); - ensure_equals("15.name::getName() failed", dst->getName(), src->getName()); - ensure_equals("16.type::getType() failed", dst->getType(), src->getType()); - - ensure_equals("17.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions()); - ensure_equals("18.description::getDescription() failed", dst->getDescription(), src->getDescription()); - ensure_equals("19.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType()); - ensure_equals("20.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice()); - ensure_equals("21.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src->getAssetUUID()); - ensure_equals("22.inventory type::getInventoryType() failed type", dst->getInventoryType(), src->getInventoryType()); - ensure_equals("23.flags::getFlags() failed", dst->getFlags(), src->getFlags()); - ensure_equals("24.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate()); - - } - - template<> template<> - void inventory_object::test<6>() - { - LLPointer<LLInventoryItem> src = create_random_inventory_item(); - - LLUUID new_item_id, new_parent_id; - new_item_id.generate(); - src->setUUID(new_item_id); - - new_parent_id.generate(); - src->setParent(new_parent_id); - - std::string new_name = "LindenLab"; - src->rename(new_name); - - src->setType(LLAssetType::AT_SOUND); - - LLUUID new_asset_id; - new_asset_id.generate(); - - src->setAssetUUID(new_asset_id); - std::string new_desc = "SecondLife Testing"; - src->setDescription(new_desc); - - S32 new_price = rand(); - LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price); - src->setSaleInfo(new_sale_info); - - U32 new_flags = rand(); - S32 new_creation = time(NULL); - - LLPermissions new_perm; - - LLUUID new_creator_id; - new_creator_id.generate(); - - LLUUID new_owner_id; - new_owner_id.generate(); - - LLUUID last_owner_id; - last_owner_id.generate(); - - LLUUID new_group_id; - new_group_id.generate(); - new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id); - new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); - src->setPermissions(new_perm); - - src->setInventoryType(LLInventoryType::IT_SOUND); - src->setFlags(new_flags); - src->setCreationDate(new_creation); - - // test a save/load cycle to LLSD and back again - LLSD sd = ll_create_sd_from_inventory_item(src); - LLPointer<LLInventoryItem> dst = new LLInventoryItem; - bool successful_parse = dst->fromLLSD(sd); - ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true); - - LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); - src1->copyItem(src); - - ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src1->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src1->getParentUUID()); - ensure_equals("3.name::getName() failed", dst->getName(), src1->getName()); - ensure_equals("4.type::getType() failed", dst->getType(), src1->getType()); - - ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src1->getPermissions()); - ensure_equals("6.description::getDescription() failed", dst->getDescription(), src1->getDescription()); - ensure_equals("7.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src1->getSaleInfo().getSaleType()); - ensure_equals("8.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src1->getSaleInfo().getSalePrice()); - ensure_equals("9.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src1->getAssetUUID()); - ensure_equals("10.inventory type::getInventoryType() failed type", dst->getInventoryType(), src1->getInventoryType()); - ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src1->getFlags()); - ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src1->getCreationDate()); - - // quick test to make sure generateUUID() really works - src1->generateUUID(); - ensure_not_equals("13.item id::generateUUID() failed", src->getUUID(), src1->getUUID()); - } - - template<> template<> - void inventory_object::test<7>() - { - std::string filename("linden_file.dat"); - llofstream fileXML(filename.c_str()); - if (!fileXML.is_open()) - { - LL_ERRS() << "file could not be opened\n" << LL_ENDL; - return; - } - - LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); - fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl; - fileXML.close(); - - - LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); - llifstream file(filename.c_str()); - if (!file.is_open()) - { - LL_ERRS() << "file could not be opened\n" << LL_ENDL; - return; - } - std::string line; - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - std::getline(file, line); - LLSD s_item; - std::istringstream iss(line); - if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) - { - LL_ERRS()<< "Parsing cache failed" << LL_ENDL; - return; - } - src2->fromLLSD(s_item); - - file.close(); - - ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); - ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); - ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); - ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); - ensure_equals("6.type::getType() failed", src1->getType(), src2->getType()); - ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); - ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); - ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); - ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - - } - - template<> template<> - void inventory_object::test<8>() - { - - LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); - - std::ostringstream ostream; - src1->exportLegacyStream(ostream, true); - - std::istringstream istream(ostream.str()); - LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); - src2->importLegacyStream(istream); - - ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); - ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); - ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); - ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); - ensure_equals("6.type::getType() failed", src1->getType(), src2->getType()); - ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); - ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); - ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); - ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - - - } - - template<> template<> - void inventory_object::test<9>() - { - // Deleted LLInventoryItem::exportFileXML() and LLInventoryItem::importXML() - // because I can't find any non-test code references to it. 2009-05-04 JC - } - - template<> template<> - void inventory_object::test<11>() - { - LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); - LLSD retSd = src1->asLLSD(); - LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); - src2->fromLLSD(retSd); - - ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); - ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); - ensure_equals("4.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); - ensure_equals("5.type::getType() failed", src1->getType(), src2->getType()); - ensure_equals("6.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); - ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags()); - ensure_equals("8.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType()); - ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); - ensure_equals("10.name::getName() failed", src1->getName(), src2->getName()); - ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription()); - ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - } - -//******class LLInventoryCategory*******// - - template<> template<> - void inventory_object::test<12>() - { - LLPointer<LLInventoryCategory> src = create_random_inventory_cat(); - LLSD sd = ll_create_sd_from_inventory_category(src); - LLPointer<LLInventoryCategory> dst = ll_create_category_from_sd(sd); - - ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); - ensure_equals("3.name::getName() failed", dst->getName(), src->getName()); - ensure_equals("4.type::getType() failed", dst->getType(), src->getType()); - ensure_equals("5.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType()); - - src->setPreferredType( LLFolderType::FT_TEXTURE); - sd = ll_create_sd_from_inventory_category(src); - dst = ll_create_category_from_sd(sd); - ensure_equals("6.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType()); - - - } - - template<> template<> - void inventory_object::test<13>() - { - std::string filename("linden_file.dat"); - llofstream fileXML(filename.c_str()); - if (!fileXML.is_open()) - { - LL_ERRS() << "file could not be opened\n" << LL_ENDL; - return; - } - - LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); - fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl; - fileXML.close(); - - llifstream file(filename.c_str()); - if (!file.is_open()) - { - LL_ERRS() << "file could not be opened\n" << LL_ENDL; - return; - } - std::string line; - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - std::getline(file, line); - LLSD s_item; - std::istringstream iss(line); - if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) - { - LL_ERRS()<< "Parsing cache failed" << LL_ENDL; - return; - } - - file.close(); - - LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); - src2->importLLSD(s_item); - - ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); - ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); - ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); - ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); - } - - template<> template<> - void inventory_object::test<14>() - { - LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); - - std::ostringstream ostream; - src1->exportLegacyStream(ostream, true); - - std::istringstream istream(ostream.str()); - LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); - src2->importLegacyStream(istream); - - ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); - ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); - ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); - ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); - ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); - - } -} +/**
+ * @file inventory.cpp
+ * @author Phoenix
+ * @date 2005-11-15
+ * @brief Functions for inventory test framework
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+
+#include "../llinventory.h"
+#include "../test/lltut.h"
+
+
+#if LL_WINDOWS
+// disable unreachable code warnings
+#pragma warning(disable: 4702)
+#endif
+
+LLPointer<LLInventoryItem> create_random_inventory_item()
+{
+ LLUUID item_id;
+ item_id.generate();
+ LLUUID parent_id;
+ parent_id.generate();
+ LLPermissions perm;
+ LLUUID creator_id;
+ creator_id.generate();
+ LLUUID owner_id;
+ owner_id.generate();
+ LLUUID last_owner_id;
+ last_owner_id.generate();
+ LLUUID group_id;
+ group_id.generate();
+ perm.init(creator_id, owner_id, last_owner_id, group_id);
+ perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
+ LLUUID asset_id;
+ asset_id.generate();
+ S32 price = rand();
+ LLSaleInfo sale_info(LLSaleInfo::FS_COPY, price);
+ U32 flags = rand();
+ S32 creation = time(NULL);
+
+ LLPointer<LLInventoryItem> item = new LLInventoryItem(
+ item_id,
+ parent_id,
+ perm,
+ asset_id,
+ LLAssetType::AT_OBJECT,
+ LLInventoryType::IT_ATTACHMENT,
+ std::string("Sample Object"),
+ std::string("Used for Testing"),
+ sale_info,
+ flags,
+ creation);
+ return item;
+}
+
+LLPointer<LLInventoryCategory> create_random_inventory_cat()
+{
+ LLUUID item_id;
+ item_id.generate();
+ LLUUID parent_id;
+ parent_id.generate();
+
+ LLPointer<LLInventoryCategory> cat = new LLInventoryCategory(
+ item_id,
+ parent_id,
+ LLFolderType::FT_NONE,
+ std::string("Sample category"));
+ return cat;
+}
+
+namespace tut
+{
+ struct inventory_data
+ {
+ };
+ typedef test_group<inventory_data> inventory_test;
+ typedef inventory_test::object inventory_object;
+ tut::inventory_test inv("LLInventory");
+
+//***class LLInventoryType***//
+
+
+ template<> template<>
+ void inventory_object::test<1>()
+ {
+ LLInventoryType::EType retType = LLInventoryType::lookup(std::string("sound"));
+ ensure("1.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SOUND);
+
+ retType = LLInventoryType::lookup(std::string("snapshot"));
+ ensure("2.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SNAPSHOT);
+ }
+
+ template<> template<>
+ void inventory_object::test<2>()
+ {
+ static std::string retType = LLInventoryType::lookup(LLInventoryType::IT_CALLINGCARD);
+ ensure("1.LLInventoryType::lookup(EType) failed", (retType == "callcard"));
+
+ retType = LLInventoryType::lookup(LLInventoryType::IT_LANDMARK);
+ ensure("2.LLInventoryType::lookup(EType) failed", (retType == "landmark"));
+
+ }
+
+ template<> template<>
+ void inventory_object::test<3>()
+ {
+ static std::string retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_CALLINGCARD);
+ ensure("1.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "calling card"));
+
+ retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_LANDMARK);
+ ensure("2.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "landmark"));
+ }
+
+ template<> template<>
+ void inventory_object::test<4>()
+ {
+ static LLInventoryType::EType retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE);
+ ensure("1.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_TEXTURE);
+
+ retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_LANDMARK);
+ ensure("2.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_LANDMARK);
+ }
+
+//*****class LLInventoryItem*****//
+
+ template<> template<>
+ void inventory_object::test<5>()
+ {
+ LLPointer<LLInventoryItem> src = create_random_inventory_item();
+ LLSD sd = ll_create_sd_from_inventory_item(src);
+ //LL_INFOS() << "sd: " << *sd << LL_ENDL;
+ LLPointer<LLInventoryItem> dst = new LLInventoryItem;
+ bool successful_parse = dst->fromLLSD(sd);
+ ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true);
+ ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
+ ensure_equals("3.name::getName() failed", dst->getName(), src->getName());
+ ensure_equals("4.type::getType() failed", dst->getType(), src->getType());
+
+ ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions());
+ ensure_equals("6.description::getDescription() failed", dst->getDescription(), src->getDescription());
+ ensure_equals("7.sale type::getSaleType() failed", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType());
+ ensure_equals("8.sale price::getSalePrice() failed", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice());
+ ensure_equals("9.asset id::getAssetUUID() failed", dst->getAssetUUID(), src->getAssetUUID());
+ ensure_equals("10.inventory type::getInventoryType() failed", dst->getInventoryType(), src->getInventoryType());
+ ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src->getFlags());
+ ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate());
+
+ LLUUID new_item_id, new_parent_id;
+ new_item_id.generate();
+ src->setUUID(new_item_id);
+
+ new_parent_id.generate();
+ src->setParent(new_parent_id);
+
+ std::string new_name = "LindenLab";
+ src->rename(new_name);
+
+ src->setType(LLAssetType::AT_SOUND);
+
+ LLUUID new_asset_id;
+ new_asset_id.generate();
+
+ src->setAssetUUID(new_asset_id);
+ std::string new_desc = "SecondLife Testing";
+ src->setDescription(new_desc);
+
+ S32 new_price = rand();
+ LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price);
+ src->setSaleInfo(new_sale_info);
+
+ U32 new_flags = rand();
+ S32 new_creation = time(NULL);
+
+ LLPermissions new_perm;
+
+ LLUUID new_creator_id;
+ new_creator_id.generate();
+
+ LLUUID new_owner_id;
+ new_owner_id.generate();
+
+ LLUUID last_owner_id;
+ last_owner_id.generate();
+
+ LLUUID new_group_id;
+ new_group_id.generate();
+ new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id);
+ new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
+ src->setPermissions(new_perm);
+
+ src->setInventoryType(LLInventoryType::IT_SOUND);
+ src->setFlags(new_flags);
+ src->setCreationDate(new_creation);
+
+ sd = ll_create_sd_from_inventory_item(src);
+ //LL_INFOS() << "sd: " << *sd << LL_ENDL;
+ successful_parse = dst->fromLLSD(sd);
+ ensure_equals("13.item id::getUUID() failed", dst->getUUID(), src->getUUID());
+ ensure_equals("14.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
+ ensure_equals("15.name::getName() failed", dst->getName(), src->getName());
+ ensure_equals("16.type::getType() failed", dst->getType(), src->getType());
+
+ ensure_equals("17.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions());
+ ensure_equals("18.description::getDescription() failed", dst->getDescription(), src->getDescription());
+ ensure_equals("19.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType());
+ ensure_equals("20.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice());
+ ensure_equals("21.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src->getAssetUUID());
+ ensure_equals("22.inventory type::getInventoryType() failed type", dst->getInventoryType(), src->getInventoryType());
+ ensure_equals("23.flags::getFlags() failed", dst->getFlags(), src->getFlags());
+ ensure_equals("24.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate());
+
+ }
+
+ template<> template<>
+ void inventory_object::test<6>()
+ {
+ LLPointer<LLInventoryItem> src = create_random_inventory_item();
+
+ LLUUID new_item_id, new_parent_id;
+ new_item_id.generate();
+ src->setUUID(new_item_id);
+
+ new_parent_id.generate();
+ src->setParent(new_parent_id);
+
+ std::string new_name = "LindenLab";
+ src->rename(new_name);
+
+ src->setType(LLAssetType::AT_SOUND);
+
+ LLUUID new_asset_id;
+ new_asset_id.generate();
+
+ src->setAssetUUID(new_asset_id);
+ std::string new_desc = "SecondLife Testing";
+ src->setDescription(new_desc);
+
+ S32 new_price = rand();
+ LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price);
+ src->setSaleInfo(new_sale_info);
+
+ U32 new_flags = rand();
+ S32 new_creation = time(NULL);
+
+ LLPermissions new_perm;
+
+ LLUUID new_creator_id;
+ new_creator_id.generate();
+
+ LLUUID new_owner_id;
+ new_owner_id.generate();
+
+ LLUUID last_owner_id;
+ last_owner_id.generate();
+
+ LLUUID new_group_id;
+ new_group_id.generate();
+ new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id);
+ new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY);
+ src->setPermissions(new_perm);
+
+ src->setInventoryType(LLInventoryType::IT_SOUND);
+ src->setFlags(new_flags);
+ src->setCreationDate(new_creation);
+
+ // test a save/load cycle to LLSD and back again
+ LLSD sd = ll_create_sd_from_inventory_item(src);
+ LLPointer<LLInventoryItem> dst = new LLInventoryItem;
+ bool successful_parse = dst->fromLLSD(sd);
+ ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true);
+
+ LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
+ src1->copyItem(src);
+
+ ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src1->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src1->getParentUUID());
+ ensure_equals("3.name::getName() failed", dst->getName(), src1->getName());
+ ensure_equals("4.type::getType() failed", dst->getType(), src1->getType());
+
+ ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src1->getPermissions());
+ ensure_equals("6.description::getDescription() failed", dst->getDescription(), src1->getDescription());
+ ensure_equals("7.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src1->getSaleInfo().getSaleType());
+ ensure_equals("8.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src1->getSaleInfo().getSalePrice());
+ ensure_equals("9.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src1->getAssetUUID());
+ ensure_equals("10.inventory type::getInventoryType() failed type", dst->getInventoryType(), src1->getInventoryType());
+ ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src1->getFlags());
+ ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src1->getCreationDate());
+
+ // quick test to make sure generateUUID() really works
+ src1->generateUUID();
+ ensure_not_equals("13.item id::generateUUID() failed", src->getUUID(), src1->getUUID());
+ }
+
+ template<> template<>
+ void inventory_object::test<7>()
+ {
+ std::string filename("linden_file.dat");
+ llofstream fileXML(filename.c_str());
+ if (!fileXML.is_open())
+ {
+ LL_ERRS() << "file could not be opened\n" << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
+ fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
+ fileXML.close();
+
+
+ LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
+ llifstream file(filename.c_str());
+ if (!file.is_open())
+ {
+ LL_ERRS() << "file could not be opened\n" << LL_ENDL;
+ return;
+ }
+ std::string line;
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
+ std::getline(file, line);
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
+ return;
+ }
+ src2->fromLLSD(s_item);
+
+ file.close();
+
+ ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
+ ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
+ ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
+ ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
+ ensure_equals("6.type::getType() failed", src1->getType(), src2->getType());
+ ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
+ ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
+ ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
+ ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
+
+ }
+
+ template<> template<>
+ void inventory_object::test<8>()
+ {
+
+ LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
+
+ std::ostringstream ostream;
+ src1->exportLegacyStream(ostream, true);
+
+ std::istringstream istream(ostream.str());
+ LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
+ src2->importLegacyStream(istream);
+
+ ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
+ ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
+ ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
+ ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
+ ensure_equals("6.type::getType() failed", src1->getType(), src2->getType());
+ ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
+ ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
+ ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
+ ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
+
+
+ }
+
+ template<> template<>
+ void inventory_object::test<9>()
+ {
+ // Deleted LLInventoryItem::exportFileXML() and LLInventoryItem::importXML()
+ // because I can't find any non-test code references to it. 2009-05-04 JC
+ }
+
+ template<> template<>
+ void inventory_object::test<11>()
+ {
+ LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
+ LLSD retSd = src1->asLLSD();
+ LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
+ src2->fromLLSD(retSd);
+
+ ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
+ ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions());
+ ensure_equals("4.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID());
+ ensure_equals("5.type::getType() failed", src1->getType(), src2->getType());
+ ensure_equals("6.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType());
+ ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags());
+ ensure_equals("8.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType());
+ ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice());
+ ensure_equals("10.name::getName() failed", src1->getName(), src2->getName());
+ ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription());
+ ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
+ }
+
+//******class LLInventoryCategory*******//
+
+ template<> template<>
+ void inventory_object::test<12>()
+ {
+ LLPointer<LLInventoryCategory> src = create_random_inventory_cat();
+ LLSD sd = ll_create_sd_from_inventory_category(src);
+ LLPointer<LLInventoryCategory> dst = ll_create_category_from_sd(sd);
+
+ ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID());
+ ensure_equals("3.name::getName() failed", dst->getName(), src->getName());
+ ensure_equals("4.type::getType() failed", dst->getType(), src->getType());
+ ensure_equals("5.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType());
+
+ src->setPreferredType( LLFolderType::FT_TEXTURE);
+ sd = ll_create_sd_from_inventory_category(src);
+ dst = ll_create_category_from_sd(sd);
+ ensure_equals("6.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType());
+
+
+ }
+
+ template<> template<>
+ void inventory_object::test<13>()
+ {
+ std::string filename("linden_file.dat");
+ llofstream fileXML(filename.c_str());
+ if (!fileXML.is_open())
+ {
+ LL_ERRS() << "file could not be opened\n" << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
+ fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
+ fileXML.close();
+
+ llifstream file(filename.c_str());
+ if (!file.is_open())
+ {
+ LL_ERRS() << "file could not be opened\n" << LL_ENDL;
+ return;
+ }
+ std::string line;
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
+ std::getline(file, line);
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
+ return;
+ }
+
+ file.close();
+
+ LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
+ src2->importLLSD(s_item);
+
+ ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
+ ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
+ ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
+ ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
+ }
+
+ template<> template<>
+ void inventory_object::test<14>()
+ {
+ LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
+
+ std::ostringstream ostream;
+ src1->exportLegacyStream(ostream, true);
+
+ std::istringstream istream(ostream.str());
+ LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
+ src2->importLegacyStream(istream);
+
+ ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
+ ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
+ ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
+ ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
+ ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
+
+ }
+}
diff --git a/indra/llinventory/tests/llparcel_test.cpp b/indra/llinventory/tests/llparcel_test.cpp index f2e4b03ff7..c6b433d468 100644 --- a/indra/llinventory/tests/llparcel_test.cpp +++ b/indra/llinventory/tests/llparcel_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llinventoryparcel_tut.cpp * @author Moss * @date 2007-04-17 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,35 +35,35 @@ namespace tut { - struct llinventoryparcel_data - { - }; - typedef test_group<llinventoryparcel_data> llinventoryparcel_test; - typedef llinventoryparcel_test::object llinventoryparcel_object; - tut::llinventoryparcel_test llinventoryparcel("LLInventoryParcel"); + struct llinventoryparcel_data + { + }; + typedef test_group<llinventoryparcel_data> llinventoryparcel_test; + typedef llinventoryparcel_test::object llinventoryparcel_object; + tut::llinventoryparcel_test llinventoryparcel("LLInventoryParcel"); - template<> template<> - void llinventoryparcel_object::test<1>() - { - for (S32 i=0; i<LLParcel::C_COUNT; ++i) - { - const std::string& catstring = LLParcel::getCategoryString(LLParcel::ECategory(i)); - ensure("LLParcel::getCategoryString(i)", - !catstring.empty()); + template<> template<> + void llinventoryparcel_object::test<1>() + { + for (S32 i=0; i<LLParcel::C_COUNT; ++i) + { + const std::string& catstring = LLParcel::getCategoryString(LLParcel::ECategory(i)); + ensure("LLParcel::getCategoryString(i)", + !catstring.empty()); - const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::ECategory(i)); - ensure("LLParcel::getCategoryUIString(i)", - !catuistring.empty()); + const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::ECategory(i)); + ensure("LLParcel::getCategoryUIString(i)", + !catuistring.empty()); - ensure_equals("LLParcel::ECategory mapping of string back to enum", LLParcel::getCategoryFromString(catstring), i); - ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), i); - } + ensure_equals("LLParcel::ECategory mapping of string back to enum", LLParcel::getCategoryFromString(catstring), i); + ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), i); + } - // test the C_ANY case, which has to work for UI strings - const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::C_ANY); - ensure("LLParcel::getCategoryUIString(C_ANY)", - !catuistring.empty()); + // test the C_ANY case, which has to work for UI strings + const std::string& catuistring = LLParcel::getCategoryUIString(LLParcel::C_ANY); + ensure("LLParcel::getCategoryUIString(C_ANY)", + !catuistring.empty()); - ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), LLParcel::C_ANY); - } + ensure_equals("LLParcel::ECategory mapping of uistring back to enum", LLParcel::getCategoryFromUIString(catuistring), LLParcel::C_ANY); + } } |