123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919 |
- /**
- * @file llparcel.cpp
- * @brief A land parcel.
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include <iostream>
- #include <utility>
- #include "indra_constants.h"
- #include "llparcel.h"
- #include "llmath.h"
- #include "llregionflags.h"
- #include "llsd.h"
- #include "llsdutil.h"
- #include "llsdutil_math.h"
- #include "llstreamtools.h"
- #include "lltransactiontypes.h"
- #include "lltransactionflags.h"
- #include "llmessage.h"
- constexpr F32 SOME_BIG_NUMBER = 1000.f;
- constexpr F32 SOME_BIG_NEG_NUMBER = -1000.f;
- 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_directory.xml category combobox
- // * floater_about_land.xml category combobox
- // * Web site "create event" tools
- // DO NOT DELETE ITEMS FROM THIS LIST WITHOUT DEEPLY UNDERSTANDING WHAT YOU ARE
- // 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 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);
- }
- 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.f;
- mUserLookAt.set(0.f, 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();
- mGraceExtension = 0;
- mAuctionID = 0;
- 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 = false;
- mMediaLoop = true;
- mMediaWidth = mMediaHeight = 0;
- setMediaCurrentURL(LLStringUtil::null);
- mMediaAllowNavigate = 1;
- mMediaPreventCameraZoom = 0;
- mMediaURLTimeout = 0.f;
- mGroupID.setNull();
- mPassPrice = PARCEL_PASS_PRICE_DEFAULT;
- mPassHours = PARCEL_PASS_HOURS_DEFAULT;
- mAABBMin.set(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER);
- mAABBMax.set(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER,
- SOME_BIG_NEG_NUMBER);
- mLocalID = INVALID_PARCEL_ID;
- setMaxPrimCapacity((S32)(sim_object_limit *
- area / (F32)(REGION_WIDTH_METERS *
- REGION_WIDTH_METERS)));
- mSimWideMaxPrimCapacity = mSimWidePrimCount = 0;
- mOwnerPrimCount = mGroupPrimCount = mOtherPrimCount = 0;
- mSelectedPrimCount = mTempPrimCount = 0;
- mCleanOtherTime = 0;
- mRegionPushOverride = mRegionDenyAnonymousOverride = false;
- mRegionDenyAgeUnverifiedOverride = false;
- mParcelPrimBonus = parcel_object_bonus;
- mPreviousOwnerID.setNull();
- mPreviouslyGroupOwned = false;
- mSeeAVs = mAllowGroupAVSounds = mAllowAnyAVSounds = true;
- mObscureMOAP = false;
- mHaveNewParcelLimitData = false;
- mRegionAllowEnvironmentOverride = false;
- mCurrentEnvironmentVersion = INVALID_PARCEL_ENVIRONMENT_VERSION;
- }
- 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::setMediaCurrentURL(const std::string& url)
- {
- mMediaCurrentURL = url;
- // The escaping here must match the escaping in the database abstraction
- // layer if it is 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::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.isNull())
- {
- // 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.isNull())
- {
- // 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;
- }
- }
- //-----------------------------------------------------------
- // File input and output
- //-----------------------------------------------------------
- // Assumes we are in a block "ParcelData"
- void LLParcel::packMessage(LLMessageSystem* msg)
- {
- msg->addU32Fast(_PREHASH_ParcelFlags, mParcelFlags);
- msg->addS32Fast(_PREHASH_SalePrice, mSalePrice);
- msg->addStringFast(_PREHASH_Name, mName);
- msg->addStringFast(_PREHASH_Desc, mDesc);
- msg->addStringFast(_PREHASH_MusicURL, mMusicURL);
- msg->addStringFast(_PREHASH_MediaURL, mMediaURL);
- msg->addU8(_PREHASH_MediaAutoScale, U8(mMediaAutoScale));
- 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". Used in the viewer, the sim uses its
- // own packer.
- void LLParcel::packMessage(LLSD& msg)
- {
- msg["local_id"] = mLocalID;
- msg["parcel_flags"] = ll_sd_from_U32(mParcelFlags);
- msg["sale_price"] = mSalePrice;
- msg["name"] = mName;
- msg["description"] = mDesc;
- msg["music_url"] = mMusicURL;
- msg["media_url"] = mMediaURL;
- msg["media_desc"] = mMediaDesc;
- msg["media_type"] = mMediaType;
- msg["media_width"] = mMediaWidth;
- msg["media_height"] = mMediaHeight;
- msg["auto_scale"] = mMediaAutoScale;
- msg["media_loop"] = mMediaLoop;
- msg["media_current_url"] = mMediaCurrentURL;
- msg["obscure_media"] = false; // OBSOLETE - no longer used
- msg["obscure_music"] = false; // OBSOLETE - no longer used
- msg["media_id"] = mMediaID;
- msg["media_allow_navigate"] = mMediaAllowNavigate;
- msg["media_prevent_camera_zoom"] = mMediaPreventCameraZoom;
- msg["media_url_timeout"] = mMediaURLTimeout;
- msg["group_id"] = mGroupID;
- 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"] = mSeeAVs;
- msg["group_av_sounds"] = mAllowGroupAVSounds;
- msg["any_av_sounds"] = mAllowAnyAVSounds;
- msg["obscure_moap"] = mObscureMOAP;
- }
- 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);
- // All default to true for legacy server behavior:
- bool see_avs = true;
- bool any_av_sounds = true;
- bool group_av_sounds = true;
- // New version of server should send all 3 of these values:
- bool have_new_parcel_limit_data = msg->getSizeFast(_PREHASH_ParcelData,
- _PREHASH_SeeAVs) > 0;
- 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(see_avs);
- setAllowAnyAVSounds(any_av_sounds);
- setAllowGroupAVSounds(group_av_sounds);
- setHaveNewParcelLimitData(have_new_parcel_limit_data);
- // non-optimized version
- U8 temp;
- msg->getU8(_PREHASH_ParcelData, _PREHASH_MediaAutoScale, temp);
- mMediaAutoScale = (bool)temp;
- 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(_PREHASH_MediaData))
- {
- msg->getString(_PREHASH_MediaData, _PREHASH_MediaDesc, buffer);
- setMediaDesc(buffer);
- msg->getString(_PREHASH_MediaData, _PREHASH_MediaType, buffer);
- setMediaType(buffer);
- msg->getS32(_PREHASH_MediaData, _PREHASH_MediaWidth, mMediaWidth);
- msg->getS32(_PREHASH_MediaData, _PREHASH_MediaHeight, mMediaHeight);
- U8 temp;
- msg->getU8(_PREHASH_MediaData, _PREHASH_MediaLoop, temp);
- mMediaLoop = (bool)temp;
- // 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(_PREHASH_MediaLinkSharing) > 0)
- {
- msg->getString(_PREHASH_MediaLinkSharing, _PREHASH_MediaCurrentURL,
- buffer);
- setMediaCurrentURL(buffer);
- msg->getU8(_PREHASH_MediaLinkSharing, _PREHASH_MediaAllowNavigate,
- mMediaAllowNavigate);
- msg->getU8(_PREHASH_MediaLinkSharing, _PREHASH_MediaPreventCameraZoom,
- mMediaPreventCameraZoom);
- msg->getF32(_PREHASH_MediaLinkSharing, _PREHASH_MediaURLTimeout,
- mMediaURLTimeout);
- }
- else
- {
- setMediaCurrentURL(LLStringUtil::null);
- }
- }
- void LLParcel::unpackAccessEntries(LLMessageSystem* msg, access_map_t* list)
- {
- LLUUID id;
- S32 time;
- U32 flags;
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
- for (S32 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())
- {
- // C++11 is not the most limpid language... This whole
- // gymnastic with piecewise_construct and forward_as_tuple is
- // here to ensure LLAccessEntry is constructed emplace, and
- // not just the UUID key of the map.
- list->emplace(std::piecewise_construct,
- std::forward_as_tuple(id),
- std::forward_as_tuple(id, time, flags));
- }
- }
- }
- void LLParcel::unpackExperienceEntries(LLMessageSystem* msg, U32 type)
- {
- LLUUID id;
- for (S32 i = 0, count = msg->getNumberOfBlocksFast(_PREHASH_List);
- i < count; ++i)
- {
- msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
- if (id.notNull())
- {
- mExperienceKeys[id] = type;
- }
- }
- }
- access_map_t LLParcel::getExperienceKeysByType(U32 type) const
- {
- access_map_t access;
- LLAccessEntry entry;
- for (xp_type_map_t::const_iterator it = mExperienceKeys.begin(),
- end = mExperienceKeys.end();
- it != end; ++it)
- {
- if (it->second == type)
- {
- entry.mID = it->first;
- access.emplace(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.hmap_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) < (U32)PARCEL_MAX_EXPERIENCE_LIST)
- {
- mExperienceKeys[experience_key] = type;
- }
- }
- U32 LLParcel::countExperienceKeyType(U32 type) const
- {
- U32 count = 0;
- for (xp_type_map_t::const_iterator it = mExperienceKeys.begin(),
- end = mExperienceKeys.end();
- it != end; ++it)
- {
- if (it->second == type)
- {
- ++count;
- }
- }
- return count;
- }
- bool LLParcel::operator==(const LLParcel& rhs) const
- {
- return mOwnerID == rhs.mOwnerID && mParcelFlags == rhs.mParcelFlags &&
- mClaimDate == rhs.mClaimDate &&
- mClaimPricePerMeter == rhs.mClaimPricePerMeter &&
- mRentPricePerMeter == rhs.mRentPricePerMeter;
- }
- // Calculates rent
- S32 LLParcel::getTotalRent() const
- {
- return (S32)floor(0.5f + (F32)mArea * (F32)mRentPricePerMeter *
- (1.f - mDiscountRate));
- }
- F32 LLParcel::getAdjustedRentPerMeter() const
- {
- return ((F32)mRentPricePerMeter * (1.f - 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.f;
- return rv;
- }
- bool LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
- {
- if (mAccessList.size() >= (U32)PARCEL_MAX_ACCESS_LIST)
- {
- return false;
- }
- if (agent_id == getOwnerID())
- {
- // Cannot add owner to these lists
- return false;
- }
- access_map_t::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.hmap_erase(itor++);
- }
- else
- {
- LL_DEBUGS("ParcelAccess") << "Agent " << agent_id
- << " already in access list ("
- << (time ? "temporary" : "permanent")
- << " access)." << LL_ENDL;
- // Existing one expires later
- return false;
- }
- }
- else
- {
- ++itor;
- }
- }
- removeFromBanList(agent_id);
- LL_DEBUGS("ParcelAccess") << "Adding agent " << agent_id << " to access list ("
- << (time ? "temporary" : "permanent")
- << " access)." << LL_ENDL;
- LLAccessEntry new_entry;
- new_entry.mID = agent_id;
- new_entry.mTime = time;
- new_entry.mFlags = 0x0;
- mAccessList[agent_id] = 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())
- {
- // Cannot add owner to these lists
- return false;
- }
- access_map_t::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.hmap_erase(itor++);
- }
- else
- {
- LL_DEBUGS("ParcelAccess") << "Agent " << agent_id
- << " already in ban list ("
- << (time ? "temporary" : "permanent")
- << " ban)." << LL_ENDL;
- // Existing one expires later
- return false;
- }
- }
- else
- {
- ++itor;
- }
- }
- removeFromAccessList(agent_id);
- LL_DEBUGS("ParcelAccess") << "Adding agent " << agent_id << " to ban list ("
- << (time ? "temporary" : "permanent") << " ban)."
- << LL_ENDL;
- LLAccessEntry new_entry;
- new_entry.mID = agent_id;
- new_entry.mTime = time;
- new_entry.mFlags = 0x0;
- mBanList[agent_id] = new_entry;
- return true;
- }
- bool remove_from_access_array(access_map_t* list, const LLUUID& agent_id)
- {
- bool removed = false;
- access_map_t::iterator it = list->begin();
- while (it != list->end())
- {
- const LLAccessEntry& entry = it->second;
- if (entry.mID == agent_id)
- {
- list->hmap_erase(it++);
- removed = true;
- }
- else
- {
- ++it;
- }
- }
- 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];
- }
- void LLParcel::dump()
- {
- llinfos << "Parcel: " << mLocalID << " - Area: " << mArea << " - Name: "
- << mName << " - Description: " << mDesc << llendl;
- }
- 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 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)
- {
- if (s.empty())
- {
- return LLParcel::C_NONE;
- }
- for (S32 i = 0; i < LLParcel::C_COUNT; ++i)
- {
- if (s == PARCEL_CATEGORY_STRING[i])
- {
- return (LLParcel::ECategory)i;
- }
- }
- llwarns << "Parcel category outside of possibilities: " << s << llendl;
- 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;
- }
|