summaryrefslogtreecommitdiff
path: root/indra/llinventory/llparcel.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 21:25:21 +0200
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-22 22:40:26 +0300
commite2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch)
tree1bb897489ce524986f6196201c10ac0d8861aa5f /indra/llinventory/llparcel.cpp
parent069ea06848f766466f1a281144c82a0f2bd79f3a (diff)
Fix line endlings
Diffstat (limited to 'indra/llinventory/llparcel.cpp')
-rw-r--r--indra/llinventory/llparcel.cpp2550
1 files changed, 1275 insertions, 1275 deletions
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 30daf0af44..ef6ddb3cab 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); });
+}