llparcel.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "indra_constants.h"
00035 #include <iostream>
00036 
00037 #include "llparcel.h"
00038 #include "llstreamtools.h"
00039 
00040 #include "llmath.h"
00041 #include "llsd.h"
00042 #include "llsdutil.h"
00043 #include "lltransactiontypes.h"
00044 #include "lltransactionflags.h"
00045 #include "llsdutil.h"
00046 #include "message.h"
00047 #include "u64.h"
00048 
00049 static const F32 SOME_BIG_NUMBER = 1000.0f;
00050 static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
00051 static const char* PARCEL_OWNERSHIP_STATUS_STRING[LLParcel::OS_COUNT] =
00052 {
00053     "leased",
00054     "lease_pending",
00055     "abandoned"
00056 };
00057 
00058 // NOTE: Adding parcel categories also requires updating:
00059 // * newview/app_settings/floater_directory.xml category combobox
00060 // * Web site "create event" tools
00061 static const char* PARCEL_CATEGORY_STRING[LLParcel::C_COUNT] =
00062 {
00063     "none",
00064     "linden",
00065     "adult",
00066     "arts",
00067     "store", // "business" legacy name
00068     "educational",
00069     "game",      // "gaming" legacy name
00070     "gather", // "hangout" legacy name
00071     "newcomer",
00072     "park",
00073     "home",      // "residential" legacy name
00074     "shopping",
00075     "stage",
00076     "other",
00077 };
00078 static const char* PARCEL_CATEGORY_UI_STRING[LLParcel::C_COUNT + 1] =
00079 {
00080     "None",
00081     "Linden Location",
00082     "Adult",
00083     "Arts & Culture",
00084     "Business",
00085     "Educational",
00086     "Gaming",
00087     "Hangout",
00088     "Newcomer Friendly",
00089     "Parks & Nature",
00090     "Residential",
00091     "Shopping",
00092     "Stage",
00093     "Other",
00094     "Any",       // valid string for parcel searches
00095 };
00096 
00097 static const char* PARCEL_ACTION_STRING[LLParcel::A_COUNT + 1] =
00098 {
00099     "create",
00100     "release",
00101     "absorb",
00102     "absorbed",
00103     "divide",
00104     "division",
00105     "acquire",
00106     "relinquish",
00107     "confirm",
00108     "unknown"
00109 };
00110 
00111 // Timeouts for parcels
00112 // default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
00113 const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
00114 // ***** TESTING is 10 minutes
00115 //const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000);
00116 
00117 // group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000
00118 const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);
00119 // ***** TESTING is 10 minutes
00120 //const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000);
00121 
00122 // default sale timeout is 2 days -> 172800000000
00123 const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);
00124 // ***** TESTING is 10 minutes
00125 //const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000);
00126 
00127 // more grace period extensions.
00128 const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);
00129 
00130 // if more than 100,000s before sale revert, and no extra extension
00131 // has been given, go ahead and extend it more. That's about 1.2 days.
00132 const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000;
00133 
00134 
00135 const char* ownership_status_to_string(LLParcel::EOwnershipStatus status);
00136 LLParcel::EOwnershipStatus ownership_string_to_status(const char* s);
00137 //const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action);
00138 //LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s);
00139 const char* category_to_string(LLParcel::ECategory category);
00140 const char* category_to_ui_string(LLParcel::ECategory category);
00141 LLParcel::ECategory category_string_to_category(const char* s);
00142 LLParcel::ECategory category_ui_string_to_category(const char* s);
00143 
00144 LLParcel::LLParcel()
00145 {
00146     init(LLUUID::null, TRUE, FALSE, FALSE, 0, 0, 0, 0, 0, 1.f, 0);
00147 }
00148 
00149 
00150 LLParcel::LLParcel(const LLUUID &owner_id,
00151                    BOOL modify, BOOL terraform, BOOL damage,
00152                    time_t claim_date, S32 claim_price_per_meter,
00153                    S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus,
00154                    BOOL is_group_owned)
00155 {
00156     init( owner_id, modify, terraform, damage, claim_date,
00157           claim_price_per_meter, rent_price_per_meter, area, sim_object_limit, parcel_object_bonus,
00158           is_group_owned);
00159 }
00160 
00161 
00162 // virtual
00163 LLParcel::~LLParcel()
00164 {
00165     // user list cleaned up by LLDynamicArray destructor.
00166 }
00167 
00168 void LLParcel::init(const LLUUID &owner_id,
00169                     BOOL modify, BOOL terraform, BOOL damage,
00170                     time_t claim_date, S32 claim_price_per_meter,
00171                     S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus,
00172                     BOOL is_group_owned)
00173 {
00174         mID.setNull();
00175         mOwnerID                        = owner_id;
00176         mGroupOwned                     = is_group_owned;
00177         mClaimDate                      = claim_date;
00178         mClaimPricePerMeter     = claim_price_per_meter;
00179         mRentPricePerMeter      = rent_price_per_meter;
00180         mArea                           = area;
00181         mDiscountRate           = 1.0f;
00182         mDrawDistance           = 512.f;
00183 
00184         mUserLookAt.setVec(0.0f, 0.f, 0.f);
00185         // Default to using the parcel's landing point, if any.
00186         mLandingType = L_LANDING_POINT;
00187 
00188         // *FIX: if owner_id != null, should be owned or sale pending,
00189         // investigate init callers.
00190         mStatus = OS_NONE;
00191         mCategory = C_NONE;
00192         mAuthBuyerID.setNull();
00193         //mBuyerID.setNull();
00194         //mJoinNeighbors = 0x0;
00195         mSaleTimerExpires.setTimerExpirySec(0);
00196         mSaleTimerExpires.stop();
00197         mGraceExtension = 0;
00198         //mExpireAction = STEA_REVERT;
00199         mRecordTransaction = FALSE;
00200 
00201         mAuctionID = 0;
00202         mInEscrow = false;
00203 
00204         mParcelFlags = PF_DEFAULT;
00205         setParcelFlag(PF_CREATE_OBJECTS,  modify);
00206         setParcelFlag(PF_ALLOW_TERRAFORM, terraform);
00207         setParcelFlag(PF_ALLOW_DAMAGE,    damage);
00208 
00209         mSalePrice                      = 10000;
00210         setName(NULL);
00211         setDesc(NULL);
00212         setMusicURL(NULL);
00213         setMediaURL(NULL);
00214         setMediaDesc(NULL);
00215         setMediaType(NULL);
00216         mMediaID.setNull();
00217         mMediaAutoScale = 0;
00218         mMediaLoop = TRUE;
00219         mObscureMedia = 1;
00220         mObscureMusic = 1;
00221         mMediaWidth = 0;
00222         mMediaHeight = 0;
00223 
00224         mGroupID.setNull();
00225 
00226         mPassPrice = PARCEL_PASS_PRICE_DEFAULT;
00227         mPassHours = PARCEL_PASS_HOURS_DEFAULT;
00228 
00229         mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER);
00230         mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER);
00231 
00232         mLocalID = 0;
00233 
00234         //mSimWidePrimCorrection = 0;
00235         setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS)));
00236         setSimWideMaxPrimCapacity(0);
00237         setSimWidePrimCount(0);
00238         setOwnerPrimCount(0);
00239         setGroupPrimCount(0);
00240         setOtherPrimCount(0);
00241         setSelectedPrimCount(0);
00242         setTempPrimCount(0);
00243         setCleanOtherTime(0);
00244         setParcelPrimBonus(parcel_object_bonus);
00245 
00246         setPreviousOwnerID(LLUUID::null);
00247         setPreviouslyGroupOwned(FALSE);
00248 }
00249 
00250 void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)
00251 {
00252     // Override with system permission (LLUUID::null)
00253     // Overridden parcels have no group
00254     mOwnerID = owner_id;
00255     mGroupOwned = is_group_owned;
00256     if(mGroupOwned)
00257     {
00258         mGroupID = mOwnerID;
00259     }
00260     else
00261     {
00262         mGroupID.setNull();
00263     }
00264     mInEscrow = false;
00265 }
00266 
00267 void LLParcel::overrideParcelFlags(U32 flags)
00268 {
00269     mParcelFlags = flags;
00270 }
00271 void set_std_string(const char* src, std::string& dest)
00272 {
00273         if(src)
00274         {
00275                 dest.assign(src);
00276         }
00277         else
00278         {
00279 #if (LL_LINUX && __GNUC__ < 3)
00280                 dest.assign(std::string(""));
00281 #else
00282                 dest.clear();
00283 #endif
00284         }
00285 }
00286 void LLParcel::setName(const LLString& name)
00287 {
00288     // The escaping here must match the escaping in the database
00289     // abstraction layer.
00290     mName = name;
00291     LLStringFn::replace_nonprintable(mName, LL_UNKNOWN_CHAR);
00292 }
00293 
00294 void LLParcel::setDesc(const LLString& desc)
00295 {
00296     // The escaping here must match the escaping in the database
00297     // abstraction layer.
00298     mDesc = desc;
00299     mDesc = rawstr_to_utf8(mDesc);
00300 }
00301 
00302 void LLParcel::setMusicURL(const LLString& url)
00303 {
00304     mMusicURL = url;
00305     // The escaping here must match the escaping in the database
00306     // abstraction layer.
00307     // This should really filter the url in some way. Other than
00308     // simply requiring non-printable.
00309     LLStringFn::replace_nonprintable(mMusicURL, LL_UNKNOWN_CHAR);
00310 }
00311 
00312 void LLParcel::setMediaURL(const LLString& url)
00313 {
00314     mMediaURL = url;
00315     // The escaping here must match the escaping in the database
00316     // abstraction layer if it's ever added.
00317     // This should really filter the url in some way. Other than
00318     // simply requiring non-printable.
00319     LLStringFn::replace_nonprintable(mMediaURL, LL_UNKNOWN_CHAR);
00320 }
00321 
00322 void LLParcel::setMediaDesc(const char* desc)
00323 {
00324         // The escaping here must match the escaping in the database
00325         // abstraction layer.
00326         set_std_string(desc, mMediaDesc);
00327         mMediaDesc = rawstr_to_utf8(mMediaDesc);
00328 }
00329 void LLParcel::setMediaType(const char* type)
00330 {
00331         // The escaping here must match the escaping in the database
00332         // abstraction layer.
00333         set_std_string(type, mMediaType);
00334         mMediaType = rawstr_to_utf8(mMediaType);
00335 
00336         // This code attempts to preserve legacy movie functioning
00337         if(mMediaType.empty() && ! mMediaURL.empty())
00338         {
00339                 setMediaType("video/vnd.secondlife.qt.legacy");
00340         }
00341 }
00342 void LLParcel::setMediaWidth(S32 width)
00343 {
00344         mMediaWidth = width;
00345 }
00346 void LLParcel::setMediaHeight(S32 height)
00347 {
00348         mMediaHeight = height;
00349 }
00350 // virtual
00351 void LLParcel::setLocalID(S32 local_id)
00352 {
00353     mLocalID = local_id;
00354 }
00355 
00356 void LLParcel::setAllParcelFlags(U32 flags)
00357 {
00358     mParcelFlags = flags;
00359 }
00360 
00361 void LLParcel::setParcelFlag(U32 flag, BOOL b)
00362 {
00363     if (b)
00364     {
00365         mParcelFlags |= flag;
00366     }
00367     else
00368     {
00369         mParcelFlags &= ~flag;
00370     }
00371 }
00372 
00373 
00374 BOOL LLParcel::allowModifyBy(const LLUUID &agent_id, const LLUUID &group_id) const
00375 {
00376     if (agent_id == LLUUID::null)
00377     {
00378         // system always can enter
00379         return TRUE;
00380     }
00381     else if (isPublic())
00382     {
00383         return TRUE;
00384     }
00385     else if (agent_id == mOwnerID)
00386     {
00387         // owner can always perform operations
00388         return TRUE;
00389     }
00390     else if (mParcelFlags & PF_CREATE_OBJECTS)
00391     {
00392         return TRUE;
00393     }
00394     else if ((mParcelFlags & PF_CREATE_GROUP_OBJECTS)
00395              && group_id.notNull() )
00396     {
00397         return (getGroupID() == group_id);
00398     }
00399     
00400     return FALSE;
00401 }
00402 
00403 BOOL LLParcel::allowTerraformBy(const LLUUID &agent_id) const
00404 {
00405     if (agent_id == LLUUID::null)
00406     {
00407         // system always can enter
00408         return TRUE;
00409     }
00410     else if(OS_LEASED == mStatus)
00411     {
00412         if(agent_id == mOwnerID)
00413         {
00414             // owner can modify leased land
00415             return TRUE;
00416         }
00417         else
00418         {
00419             // otherwise check other people
00420             return mParcelFlags & PF_ALLOW_TERRAFORM;
00421         }
00422     }
00423     else
00424     {
00425         return FALSE;
00426     }
00427 }
00428 
00429 
00430 bool LLParcel::isAgentBlockedFromParcel(LLParcel* parcelp,
00431                                         const LLUUID& agent_id,
00432                                         const std::vector<LLUUID>& group_ids,
00433                                         const BOOL is_agent_identified,
00434                                         const BOOL is_agent_transacted,
00435                                         const BOOL is_agent_ageverified)
00436 {
00437     S32 current_group_access = parcelp->blockAccess(agent_id, LLUUID::null, is_agent_identified, is_agent_transacted, is_agent_ageverified);
00438     S32 count;
00439     bool is_allowed = (current_group_access == BA_ALLOWED) ? true: false;
00440     LLUUID group_id;
00441     
00442     count = group_ids.size();
00443     for (int i = 0; i < count && !is_allowed; i++)
00444     {
00445         group_id = group_ids[i];
00446         current_group_access = parcelp->blockAccess(agent_id, group_id, is_agent_identified, is_agent_transacted, is_agent_ageverified);
00447         
00448         if (current_group_access == BA_ALLOWED) is_allowed = true;
00449     }
00450     
00451     return !is_allowed;
00452 }
00453 
00454 BOOL LLParcel::isAgentBanned(const LLUUID& agent_id) const
00455 {
00456         // Test ban list
00457         if (mBanList.find(agent_id) != mBanList.end())
00458         {
00459                 return TRUE;
00460         }
00461     
00462     return FALSE;
00463 }
00464 
00465 S32 LLParcel::blockAccess(const LLUUID& agent_id, const LLUUID& group_id,
00466                           const BOOL is_agent_identified,
00467                           const BOOL is_agent_transacted,
00468                           const BOOL is_agent_ageverified) const
00469 {
00470     // Test ban list
00471     if (isAgentBanned(agent_id))
00472     {
00473         return BA_BANNED;
00474     }
00475     
00476     // Always allow owner on (unless he banned himself, useful for
00477     // testing). We will also allow estate owners/managers in if they 
00478     // are not explicitly banned.
00479     if (agent_id == mOwnerID)
00480     {
00481         return BA_ALLOWED;
00482     }
00483     
00484     // Special case when using pass list where group access is being restricted but not 
00485     // using access list.        In this case group members are allowed only if they buy a pass.
00486     // We return BA_NOT_IN_LIST if not in list
00487     BOOL passWithGroup = getParcelFlag(PF_USE_PASS_LIST) && !getParcelFlag(PF_USE_ACCESS_LIST) 
00488     && getParcelFlag(PF_USE_ACCESS_GROUP) && !mGroupID.isNull() && group_id == mGroupID;
00489     
00490     
00491     // Test group list
00492     if (getParcelFlag(PF_USE_ACCESS_GROUP)
00493         && !mGroupID.isNull()
00494         && group_id == mGroupID
00495         && !passWithGroup)
00496     {
00497         return BA_ALLOWED;
00498     }
00499     
00500     // Test access list
00501     if (getParcelFlag(PF_USE_ACCESS_LIST) || passWithGroup )
00502     {
00503         if (mAccessList.find(agent_id) != mAccessList.end())
00504         {
00505             return BA_ALLOWED;
00506         }
00507         
00508         return BA_NOT_ON_LIST; 
00509     }
00510     
00511     // If we're not doing any other limitations, all users
00512     // can enter, unless
00513     if (                 !getParcelFlag(PF_USE_ACCESS_GROUP)
00514                  && !getParcelFlag(PF_USE_ACCESS_LIST))
00515     { 
00516         //If the land is group owned, and you are in the group, bypass these checks
00517         if(getIsGroupOwned() && group_id == mGroupID)
00518         {
00519             return BA_ALLOWED;
00520         }
00521         
00522         // Test for "payment" access levels
00523         // Anonymous - No Payment Info on File
00524         if(getParcelFlag(PF_DENY_ANONYMOUS) && !is_agent_identified && !is_agent_transacted)
00525         {
00526             return BA_NO_ACCESS_LEVEL;
00527         }
00528         // AgeUnverified - Not Age Verified
00529         if(getParcelFlag(PF_DENY_AGEUNVERIFIED) && !is_agent_ageverified)
00530         {
00531                         return BA_NOT_AGE_VERIFIED;
00532         }
00533     
00534         return BA_ALLOWED;
00535     }
00536     
00537     return BA_NOT_IN_GROUP;
00538     
00539 }
00540 
00541 
00542 void LLParcel::setArea(S32 area, S32 sim_object_limit)
00543 {
00544     mArea = area;
00545     setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS)));
00546 }
00547 
00548 void LLParcel::setDiscountRate(F32 rate)
00549 {
00550     // this is to make sure that the rate is at least sane - this is
00551     // not intended to enforce economy rules. It only enfoces that the
00552     // rate is a scaler between 0 and 1.
00553     mDiscountRate = llclampf(rate);
00554 }
00555 
00556 
00557 //-----------------------------------------------------------
00558 // File input and output
00559 //-----------------------------------------------------------
00560 
00561 
00562 // WARNING: Area will be wrong until you calculate it.
00563 BOOL LLParcel::importStream(std::istream& input_stream)
00564 {
00565         U32 setting;
00566         S32 secs_until_revert = 0;
00567 
00568         skip_to_end_of_next_keyword("{", input_stream);
00569         if (!input_stream.good()) 
00570         {
00571                 llwarns << "LLParcel::importStream() - bad input_stream" << llendl;
00572                 return FALSE;
00573         }
00574 
00575         while (input_stream.good())
00576         {
00577                 skip_comments_and_emptyspace(input_stream);
00578                 LLString line, keyword, value;
00579                 get_line(line, input_stream, MAX_STRING);
00580                 get_keyword_and_value(keyword, value, line);
00581 
00582                 if ("}" == keyword)
00583                 {
00584                         break;
00585                 }
00586                 else if ("parcel_id" == keyword)
00587                 {
00588                         mID.set(value.c_str());
00589                 }
00590                 else if ("status" == keyword)
00591                 {
00592                         mStatus = ownership_string_to_status(value.c_str());
00593                 }
00594                 else if ("category" == keyword)
00595                 {
00596                         mCategory = category_string_to_category(value.c_str());
00597                 }
00598                 else if ("local_id" == keyword)
00599                 {
00600                         LLString::convertToS32(value, mLocalID);
00601                 }
00602                 else if ("name" == keyword)
00603                 {
00604                         setName( value );
00605                 }
00606                 else if ("desc" == keyword)
00607                 {
00608                         setDesc( value );
00609                 }
00610                 else if ("music_url" == keyword)
00611                 {
00612                         setMusicURL( value );
00613                 }
00614                 else if ("media_url" == keyword)
00615                 {
00616                         setMediaURL( value );
00617                 }
00618                 else if ("media_desc" == keyword)
00619                 {
00620                         setMediaDesc( value.c_str() );
00621                 }
00622                 else if ("media_type" == keyword)
00623                 {
00624                         setMediaType( value.c_str() );
00625                 }
00626                 else if ("media_width" == keyword)
00627                 {
00628                         S32 width;
00629                         LLString::convertToS32(value, width);
00630                         setMediaWidth( width );
00631                 }
00632                 else if ("media_height" == keyword)
00633                 {
00634                         S32 height;
00635                         LLString::convertToS32(value, height);
00636                         setMediaHeight( height );
00637                 }
00638                 else if ("media_id" == keyword)
00639                 {
00640                         mMediaID.set( value.c_str() );
00641                 }
00642                 else if ("media_auto_scale" == keyword)
00643                 {
00644                         LLString::convertToU8(value, mMediaAutoScale);
00645                 }
00646                 else if ("media_loop" == keyword)
00647                 {
00648                         LLString::convertToU8(value, mMediaLoop);
00649                 }
00650                 else if ("obscure_media" == keyword)
00651                 {
00652                         LLString::convertToU8(value, mObscureMedia);
00653                 }               
00654                 else if ("obscure_music" == keyword)
00655                 {
00656                         LLString::convertToU8(value, mObscureMusic);
00657                 }               
00658                 else if ("owner_id" == keyword)
00659                 {
00660                         mOwnerID.set( value.c_str() );
00661                 }
00662                 else if ("group_owned" == keyword)
00663                 {
00664                         LLString::convertToBOOL(value, mGroupOwned);
00665                 }
00666                 else if ("clean_other_time" == keyword)
00667                 {
00668                         S32 time;
00669                         LLString::convertToS32(value, time);
00670                         setCleanOtherTime(time);
00671                 }
00672                 else if ("auth_buyer_id" == keyword)
00673                 {
00674                         mAuthBuyerID.set(value.c_str());
00675                 }
00676                 else if ("snapshot_id" == keyword)
00677                 {
00678                         mSnapshotID.set(value.c_str());
00679                 }
00680                 else if ("user_location" == keyword)
00681                 {
00682                         sscanf(value.c_str(), "%f %f %f",
00683                                 &mUserLocation.mV[VX],
00684                                 &mUserLocation.mV[VY],
00685                                 &mUserLocation.mV[VZ]);
00686                 }
00687                 else if ("user_look_at" == keyword)
00688                 {
00689                         sscanf(value.c_str(), "%f %f %f",
00690                                 &mUserLookAt.mV[VX],
00691                                 &mUserLookAt.mV[VY],
00692                                 &mUserLookAt.mV[VZ]);
00693                 }
00694                 else if ("landing_type" == keyword)
00695                 {
00696                         S32 landing_type = 0;
00697                         LLString::convertToS32(value, landing_type);
00698                         mLandingType = (ELandingType) landing_type;
00699                 }
00700                 else if ("join_neighbors" == keyword)
00701                 {
00702                         llinfos << "found deprecated keyword join_neighbors" << llendl;
00703                 }
00704                 else if ("revert_sale" == keyword)
00705                 {
00706                         LLString::convertToS32(value, secs_until_revert);
00707                         if (secs_until_revert > 0)
00708                         {
00709                                 mSaleTimerExpires.start();
00710                                 mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert);
00711                         }
00712                 }
00713                 else if("extended_grace" == keyword)
00714                 {
00715                         LLString::convertToS32(value, mGraceExtension);
00716                 }
00717                 else if ("user_list_type" == keyword)
00718                 {
00719                         // deprecated
00720                 }
00721                 else if("auction_id" == keyword)
00722                 {
00723                         LLString::convertToU32(value, mAuctionID);
00724                 }
00725                 else if ("allow_modify" == keyword)
00726                 {
00727                         LLString::convertToU32(value, setting);
00728                         setParcelFlag(PF_CREATE_OBJECTS, setting);
00729                 }
00730                 else if ("allow_group_modify" == keyword)
00731                 {
00732                         LLString::convertToU32(value, setting);
00733                         setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting);
00734                 }
00735                 else if ("allow_all_object_entry" == keyword)
00736                 {
00737                         LLString::convertToU32(value, setting);
00738                         setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting);
00739                 }
00740                 else if ("allow_group_object_entry" == keyword)
00741                 {
00742                         LLString::convertToU32(value, setting);
00743                         setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting);
00744                 }
00745                 else if ("allow_deed_to_group" == keyword)
00746                 {
00747                         LLString::convertToU32(value, setting);
00748                         setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting);
00749                 }
00750                 else if("contribute_with_deed" == keyword)
00751                 {
00752                         LLString::convertToU32(value, setting);
00753                         setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting);
00754                 }
00755                 else if ("allow_terraform" == keyword)
00756                 {
00757                         LLString::convertToU32(value, setting);
00758                         setParcelFlag(PF_ALLOW_TERRAFORM, setting);
00759                 }
00760                 else if ("allow_damage" == keyword)
00761                 {
00762                         LLString::convertToU32(value, setting);
00763                         setParcelFlag(PF_ALLOW_DAMAGE, setting);
00764                 }
00765                 else if ("allow_fly" == keyword)
00766                 {
00767                         LLString::convertToU32(value, setting);
00768                         setParcelFlag(PF_ALLOW_FLY, setting);
00769                 }
00770                 else if ("allow_landmark" == keyword)
00771                 {
00772                         LLString::convertToU32(value, setting);
00773                         setParcelFlag(PF_ALLOW_LANDMARK, setting);
00774                 }
00775                 else if ("sound_local" == keyword)
00776                 {
00777                         LLString::convertToU32(value, setting);
00778                         setParcelFlag(PF_SOUND_LOCAL, setting);
00779                 }
00780                 else if ("allow_group_scripts" == keyword)
00781                 {
00782                         LLString::convertToU32(value, setting);
00783                         setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting);
00784                 }
00785                 else if ("allow_voice_chat" == keyword)
00786                 {
00787                         LLString::convertToU32(value, setting);
00788                         setParcelFlag(PF_ALLOW_VOICE_CHAT, setting);
00789                 }
00790                 else if ("use_estate_voice_chan" == keyword)
00791                 {
00792                         LLString::convertToU32(value, setting);
00793                         setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting);
00794                 }
00795                 else if ("allow_scripts" == keyword)
00796                 {
00797                         LLString::convertToU32(value, setting);
00798                         setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting);
00799                 }
00800                 else if ("for_sale" == keyword)
00801                 {
00802                         LLString::convertToU32(value, setting);
00803                         setParcelFlag(PF_FOR_SALE, setting);
00804                 }
00805                 else if ("sell_w_objects" == keyword)
00806                 {
00807                         LLString::convertToU32(value, setting);
00808                         setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting);
00809                 }
00810                 else if ("use_pass_list" == keyword)
00811                 {
00812                         LLString::convertToU32(value, setting);
00813                         setParcelFlag(PF_USE_PASS_LIST, setting);
00814                 }
00815                 else if ("show_directory" == keyword)
00816                 {
00817                         LLString::convertToU32(value, setting);
00818                         setParcelFlag(PF_SHOW_DIRECTORY, setting);
00819                 }
00820                 else if ("allow_publish" == keyword)
00821                 {
00822                         LLString::convertToU32(value, setting);
00823                         setParcelFlag(PF_ALLOW_PUBLISH, setting);
00824                 }
00825                 else if ("mature_publish" == keyword)
00826                 {
00827                         LLString::convertToU32(value, setting);
00828                         setParcelFlag(PF_MATURE_PUBLISH, setting);
00829                 }
00830                 else if ("claim_date" == keyword)
00831                 {
00832                         // BUG: This will fail when time rolls over in 2038.
00833                         S32 time;
00834                         LLString::convertToS32(value, time);
00835                         mClaimDate = time;
00836                 }
00837                 else if ("claim_price" == keyword)
00838                 {
00839                         LLString::convertToS32(value, mClaimPricePerMeter);
00840                 }
00841                 else if ("rent_price" == keyword)
00842                 {
00843                         LLString::convertToS32(value, mRentPricePerMeter);
00844                 }
00845                 else if ("discount_rate" == keyword)
00846                 {
00847                         LLString::convertToF32(value, mDiscountRate);
00848                 }
00849                 else if ("draw_distance" == keyword)
00850                 {
00851                         LLString::convertToF32(value, mDrawDistance);
00852                 }
00853                 else if ("sale_price" == keyword)
00854                 {
00855                         LLString::convertToS32(value, mSalePrice);
00856                 }
00857                 else if ("pass_price" == keyword)
00858                 {
00859                         LLString::convertToS32(value, mPassPrice);
00860                 }
00861                 else if ("pass_hours" == keyword)
00862                 {
00863                         LLString::convertToF32(value, mPassHours);
00864                 }
00865                 else if ("box" == keyword)
00866                 {
00867                         // deprecated
00868                 }
00869                 else if ("aabb_min" == keyword)
00870                 {
00871                         sscanf(value.c_str(), "%f %f %f", 
00872                                 &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]);
00873                 }
00874                 else if ("use_access_group" == keyword)
00875                 {
00876                         LLString::convertToU32(value, setting);
00877                         setParcelFlag(PF_USE_ACCESS_GROUP, setting);
00878                 }
00879                 else if ("use_access_list" == keyword)
00880                 {
00881                         LLString::convertToU32(value, setting);
00882                         setParcelFlag(PF_USE_ACCESS_LIST, setting);
00883                 }
00884                 else if ("use_ban_list" == keyword)
00885                 {
00886                         LLString::convertToU32(value, setting);
00887                         setParcelFlag(PF_USE_BAN_LIST, setting);
00888                 }
00889                 else if ("group_name" == keyword)
00890                 {
00891                         llinfos << "found deprecated keyword group_name" << llendl;
00892                 }
00893                 else if ("group_id" == keyword)
00894                 {
00895                         mGroupID.set( value.c_str() );
00896                 }
00897                 // TODO: DEPRECATED FLAG
00898                 // Flag removed from simstate files in 1.11.1
00899                 // Remove at some point where we have guarenteed this flag
00900                 // no longer exists anywhere in simstate files.
00901                 else if ("require_identified" == keyword)
00902                 {
00903                         // LLString::convertToU32(value, setting);
00904                         // setParcelFlag(PF_DENY_ANONYMOUS, setting);
00905                 }
00906                 // TODO: DEPRECATED FLAG
00907                 // Flag removed from simstate files in 1.11.1
00908                 // Remove at some point where we have guarenteed this flag
00909                 // no longer exists anywhere in simstate files.
00910                 else if ("require_transacted" == keyword)
00911                 {
00912                         // LLString::convertToU32(value, setting);
00913                         // setParcelFlag(PF_DENY_ANONYMOUS, setting);
00914                         // setParcelFlag(PF_DENY_IDENTIFIED, setting);
00915                 }
00916                 else if ("restrict_pushobject" == keyword)
00917                 {
00918                         LLString::convertToU32(value, setting);
00919                         setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting);
00920                 }
00921                 else if ("deny_anonymous" == keyword)
00922                 {
00923                         LLString::convertToU32(value, setting);
00924                         setParcelFlag(PF_DENY_ANONYMOUS, setting);
00925                 }
00926                 else if ("deny_identified" == keyword)
00927                 {
00928 //                      LLString::convertToU32(value, setting);
00929 //                      setParcelFlag(PF_DENY_IDENTIFIED, setting);
00930                 }
00931                 else if ("deny_transacted" == keyword)
00932                 {
00933 //                      LLString::convertToU32(value, setting);
00934 //                      setParcelFlag(PF_DENY_TRANSACTED, setting);
00935                 }
00936         else if ("deny_age_unverified" == keyword)
00937         {
00938             LLString::convertToU32(value, setting);
00939             setParcelFlag(PF_DENY_AGEUNVERIFIED, setting);
00940         }
00941         else if ("access_list" == keyword)
00942         {
00943             S32 entry_count = 0;
00944             LLString::convertToS32(value, entry_count);
00945             for (S32 i = 0; i < entry_count; i++)
00946             {
00947                 LLAccessEntry entry;
00948                 if (importAccessEntry(input_stream, &entry))
00949                 {
00950                     mAccessList[entry.mID] = entry;
00951                 }
00952             }
00953         }
00954         else if ("ban_list" == keyword)
00955         {
00956             S32 entry_count = 0;
00957             LLString::convertToS32(value, entry_count);
00958             for (S32 i = 0; i < entry_count; i++)
00959             {
00960                 LLAccessEntry entry;
00961                 if (importAccessEntry(input_stream, &entry))
00962                 {
00963                     mBanList[entry.mID] = entry;
00964                 }
00965             }
00966         }
00967         else if ("renter_list" == keyword)
00968         {
00969             /*
00970              S32 entry_count = 0;
00971              LLString::convertToS32(value, entry_count);
00972              for (S32 i = 0; i < entry_count; i++)
00973              {
00974                  LLAccessEntry entry;
00975                  if (importAccessEntry(input_stream, &entry))
00976                  {
00977                      mRenterList.put(entry);
00978                  }
00979              }*/
00980         }
00981         else if ("pass_list" == keyword)
00982         {
00983             // legacy - put into access list
00984             S32 entry_count = 0;
00985             LLString::convertToS32(value, entry_count);
00986             for (S32 i = 0; i < entry_count; i++)
00987             {
00988                 LLAccessEntry entry;
00989                 if (importAccessEntry(input_stream, &entry))
00990                 {
00991                     mAccessList[entry.mID] = entry;
00992                 }
00993             }
00994         }
00995         
00996         else
00997         {
00998             llwarns << "Unknown keyword in parcel section: <" 
00999             << keyword << ">" << llendl;
01000         }
01001     }
01002     
01003     // this code block detects if we have loaded a 1.1 simstate file,
01004     // and follows the conversion rules specified in
01005     // design_docs/land/pay_for_parcel.txt.
01006     F32 time_to_expire = 0.0f;
01007     if(mID.isNull())
01008     {
01009         mID.generate();
01010         mStatus = OS_LEASE_PENDING;
01011         //mBuyerID = mOwnerID;
01012         if(getIsGroupOwned())
01013         {
01014             time_to_expire += GROUP_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC;
01015         }
01016         else
01017         {
01018             time_to_expire += DEFAULT_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC;
01019         }
01020         //mExpireAction = STEA_PUBLIC;
01021         mRecordTransaction = TRUE;
01022     }
01023     
01024     // this code block deals with giving an extension to pending
01025     // parcels to the midday of 2004-01-19 if they were originally set
01026     // for some time on 2004-01-12.
01027     if((0 == mGraceExtension)
01028        && (EXTEND_GRACE_IF_MORE_THAN_SEC < secs_until_revert))
01029     {
01030         const S32 NEW_CONVERSION_DATE = 1074538800; // 2004-01-19T11:00:00
01031         time_t now = time(NULL); // now in epoch
01032         secs_until_revert = (S32)(NEW_CONVERSION_DATE - now);
01033         time_to_expire = (F32)secs_until_revert;
01034         mGraceExtension = 1;
01035     }
01036     
01037     // This code block adds yet another week to the deadline. :(
01038     if(1 == mGraceExtension)
01039     {
01040         time_to_expire += SEVEN_DAYS_IN_USEC / SEC_TO_MICROSEC;
01041         mGraceExtension = 2;
01042     }
01043     
01044     if (time_to_expire > 0)
01045     {
01046         mSaleTimerExpires.setTimerExpirySec(time_to_expire);
01047         mSaleTimerExpires.start();
01048     }
01049     
01050     // successful import
01051     return TRUE;
01052 }
01053 
01054 
01055 BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entry)
01056 {
01057     skip_to_end_of_next_keyword("{", input_stream);
01058     while (input_stream.good())
01059     {
01060         skip_comments_and_emptyspace(input_stream);
01061         LLString line, keyword, value;
01062         get_line(line, input_stream, MAX_STRING);
01063         get_keyword_and_value(keyword, value, line);
01064         
01065         if ("}" == keyword)
01066         {
01067             break;
01068         }
01069         else if ("id" == keyword)
01070         {
01071             entry->mID.set( value.c_str() );
01072         }
01073         else if ("name" == keyword)
01074         {
01075             // deprecated
01076         }
01077         else if ("time" == keyword)
01078         {
01079             S32 when;
01080             LLString::convertToS32(value, when);
01081             entry->mTime = when;
01082         }
01083         else if ("flags" == keyword)
01084         {
01085             U32 setting;
01086             LLString::convertToU32(value, setting);
01087             entry->mFlags = setting;
01088         }
01089         else
01090         {
01091             llwarns << "Unknown keyword in parcel access entry section: <" 
01092             << keyword << ">" << llendl;
01093         }
01094     }
01095     return input_stream.good();
01096 }
01097 
01098 BOOL LLParcel::exportStream(std::ostream& output_stream)
01099 {
01100         S32 setting;
01101         char id_string[MAX_STRING];     /* Flawfinder: ignore */
01102 
01103         std::ios::fmtflags old_flags = output_stream.flags();
01104         output_stream.setf(std::ios::showpoint);
01105         output_stream << "\t{\n";
01106 
01107         mID.toString(id_string);
01108         output_stream << "\t\t parcel_id        " << id_string << "\n";
01109         output_stream << "\t\t status           " << ownership_status_to_string(mStatus) << "\n";
01110         output_stream << "\t\t category         " << category_to_string(mCategory) << "\n";
01111 
01112         output_stream << "\t\t local_id         " << mLocalID  << "\n";
01113 
01114         const char* name = (mName.empty() ? "" : mName.c_str() );
01115         output_stream << "\t\t name             " << name << "\n";
01116 
01117         const char* desc = (mDesc.empty() ? "" : mDesc.c_str() );
01118         output_stream << "\t\t desc             " << desc << "\n";
01119 
01120         const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() );
01121         output_stream << "\t\t music_url        " << music_url << "\n";
01122 
01123         const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() );
01124         output_stream << "\t\t media_url        " << media_url << "\n";
01125 
01126         const char* media_type = (mMediaType.empty() ? "" : mMediaType.c_str() );
01127         output_stream << "\t\t media_type             " << media_type << "\n";
01128 
01129         const char* media_desc = (mMediaDesc.empty() ? "" : mMediaDesc.c_str() );
01130         output_stream << "\t\t media_desc             " << media_desc << "\n";
01131 
01132         output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0)  << "\n";
01133         output_stream << "\t\t media_loop " << (mMediaLoop ? 1 : 0)  << "\n";
01134         output_stream << "\t\t obscure_media " << (mObscureMedia ? 1 : 0)  << "\n";
01135         output_stream << "\t\t obscure_music " << (mObscureMusic ? 1 : 0)  << "\n";
01136 
01137         mMediaID.toString(id_string);
01138         output_stream << "\t\t media_id         " << id_string  << "\n";
01139 
01140         output_stream << "\t\t media_width     " << mMediaWidth  << "\n";
01141         output_stream << "\t\t media_height     " << mMediaHeight  << "\n";
01142 
01143         mOwnerID.toString(id_string);
01144         output_stream << "\t\t owner_id         " << id_string  << "\n";
01145         output_stream << "\t\t group_owned         " << (mGroupOwned ? 1 : 0)  << "\n";
01146         output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n";
01147 
01148         if(!mAuthBuyerID.isNull())
01149         {
01150                 mAuthBuyerID.toString(id_string);
01151                 output_stream << "\t\t auth_buyer_id    " << id_string << "\n";
01152         }
01153         if (!mSnapshotID.isNull())
01154         {
01155                 mSnapshotID.toString(id_string);
01156                 output_stream << "\t\t snapshot_id      " << id_string << "\n";
01157         }
01158         if (!mUserLocation.isExactlyZero())
01159         {
01160                 output_stream << "\t\t user_location " 
01161                         << (F64)mUserLocation.mV[VX]
01162                         << " " << (F64)mUserLocation.mV[VY]
01163                         << " " << (F64)mUserLocation.mV[VZ] << "\n";
01164                 output_stream << "\t\t user_look_at " 
01165                         << (F64)mUserLookAt.mV[VX]
01166                         << " " << (F64)mUserLookAt.mV[VY]
01167                         << " " << (F64)mUserLookAt.mV[VZ] << "\n";
01168         }
01169         output_stream << "\t\t landing_type " << mLandingType << "\n";
01170         //if(mJoinNeighbors)
01171         //{
01172         //      output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n";
01173         //}
01174         if(mSaleTimerExpires.getStarted())
01175         {
01176                 S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions
01177                 output_stream << "\t\t revert_sale      " << dt_sec << "\n";
01178                 //output_stream << "\t\t revert_action    " << revert_action_to_string(mExpireAction) << "\n";
01179                 output_stream << "\t\t extended_grace   " << mGraceExtension << "\n";
01180         }
01181 
01182         if(0 != mAuctionID)
01183         {
01184                 output_stream << "\t\t auction_id       " << mAuctionID << "\n";
01185         }
01186 
01187         output_stream << "\t\t allow_modify     " << getAllowModify()  << "\n";
01188         output_stream << "\t\t allow_group_modify     " << getAllowGroupModify()  << "\n";
01189         output_stream << "\t\t allow_all_object_entry     " << getAllowAllObjectEntry()  << "\n";
01190         output_stream << "\t\t allow_group_object_entry     " << getAllowGroupObjectEntry()  << "\n";
01191         output_stream << "\t\t allow_terraform  " << getAllowTerraform()  << "\n";
01192         output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup()  << "\n";
01193         output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n";
01194         output_stream << "\t\t allow_damage     " << getAllowDamage()  << "\n";
01195         output_stream << "\t\t claim_date       " << (S32)mClaimDate  << "\n";
01196         output_stream << "\t\t claim_price      " << mClaimPricePerMeter  << "\n";
01197         output_stream << "\t\t rent_price       " << mRentPricePerMeter  << "\n";
01198         output_stream << "\t\t discount_rate    " << mDiscountRate  << "\n";
01199         output_stream << "\t\t allow_fly        " << (getAllowFly()      ? 1 : 0)  << "\n";
01200         output_stream << "\t\t allow_landmark   " << (getAllowLandmark() ? 1 : 0)  << "\n";
01201         output_stream << "\t\t sound_local         " << (getSoundLocal() ? 1 : 0)  << "\n";
01202         output_stream << "\t\t allow_scripts    " << (getAllowOtherScripts()  ? 1 : 0)  << "\n";
01203         output_stream << "\t\t allow_group_scripts    " << (getAllowGroupScripts()  ? 1 : 0)  << "\n";
01204         output_stream << "\t\t allow_voice_chat    " << (getVoiceEnabled() ? 1 : 0) << "\n";
01205         output_stream << "\t\t use_estate_voice_chan   " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n";
01206         output_stream << "\t\t for_sale         " << (getForSale()       ? 1 : 0)  << "\n";
01207         output_stream << "\t\t sell_w_objects   " << (getSellWithObjects()      ? 1 : 0)  << "\n";
01208         output_stream << "\t\t draw_distance    " << mDrawDistance  << "\n";
01209         output_stream << "\t\t sale_price       " << mSalePrice  << "\n";
01210 
01211         setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0);
01212         output_stream << "\t\t use_access_group " << setting  << "\n";
01213 
01214         setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0);
01215         output_stream << "\t\t use_access_list  " << setting  << "\n";
01216 
01217         setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0);
01218         output_stream << "\t\t use_ban_list     " << setting  << "\n";
01219 
01220         mGroupID.toString(id_string);
01221         output_stream << "\t\t group_id  " << id_string  << "\n";
01222 
01223         //const char* group_name
01224         //      = (mGroupName.isEmpty() ? "" : mGroupName.c_str() );
01225         //output_stream << "\t\t group_name " << group_name << "\n";
01226 
01227         setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0);
01228         output_stream << "\t\t use_pass_list    " << setting  << "\n";
01229 
01230         output_stream << "\t\t pass_price       " << mPassPrice  << "\n";
01231         output_stream << "\t\t pass_hours       " << mPassHours  << "\n";
01232 
01233         setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0);
01234         output_stream << "\t\t show_directory   " << setting  << "\n";
01235 
01236         setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0);
01237         output_stream << "\t\t allow_publish     " << setting  << "\n";
01238 
01239         setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0);
01240         output_stream << "\t\t mature_publish     " << setting  << "\n";
01241 
01242         setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0);
01243         output_stream << "\t\t deny_anonymous     " << setting  << "\n";
01244 
01245 //      setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0);
01246 //      output_stream << "\t\t deny_identified     " << setting  << "\n";
01247 
01248 //      setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0);
01249 //      output_stream << "\t\t deny_transacted     " << setting  << "\n";
01250 
01251         setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0);
01252         output_stream << "\t\t deny_age_unverified                       " << setting  << "\n";
01253 
01254         setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0);
01255         output_stream << "\t\t restrict_pushobject " << setting  << "\n";
01256 
01257         output_stream << "\t\t aabb_min         " 
01258                 << mAABBMin.mV[VX]
01259                 << " " << mAABBMin.mV[VY]
01260                 << " " << mAABBMin.mV[VZ] << "\n";
01261 
01262         if (!mAccessList.empty())
01263         {
01264                 output_stream << "\t\t access_list " << mAccessList.size()  << "\n";
01265                 access_map_const_iterator cit = mAccessList.begin();
01266                 access_map_const_iterator end = mAccessList.end();
01267 
01268                 for ( ; cit != end; ++cit)
01269                 {
01270                         output_stream << "\t\t{\n";
01271                         const LLAccessEntry& entry = (*cit).second;
01272                         entry.mID.toString(id_string);
01273                         output_stream << "\t\t\tid " << id_string << "\n";
01274                         output_stream << "\t\t\ttime " << entry.mTime  << "\n";
01275                         output_stream << "\t\t\tflags " << entry.mFlags  << "\n";
01276                         output_stream << "\t\t}\n";
01277                 }
01278         }
01279 
01280         if (!mBanList.empty())
01281         {
01282                 output_stream << "\t\t ban_list " << mBanList.size()  << "\n";
01283                 access_map_const_iterator cit = mBanList.begin();
01284                 access_map_const_iterator end = mBanList.end();
01285 
01286                 for ( ; cit != end; ++cit)
01287                 {
01288                         output_stream << "\t\t{\n";
01289                         const LLAccessEntry& entry = (*cit).second;
01290                         entry.mID.toString(id_string);
01291                         output_stream << "\t\t\tid " << id_string << "\n";
01292                         output_stream << "\t\t\ttime " << entry.mTime  << "\n";
01293                         output_stream << "\t\t\tflags " << entry.mFlags  << "\n";
01294                         output_stream << "\t\t}\n";
01295                 }
01296         }
01297 
01298         /*if (mRenterList.count() > 0)
01299         {
01300                 output_stream << "\t\t renter_list " << mRenterList.count()  << "\n";
01301                 for (i = 0; i < mRenterList.count(); i++)
01302                 {
01303                         output_stream << "\t\t{\n";
01304                         const LLAccessEntry& entry = mRenterList.get(i);
01305                         entry.mID.toString(id_string);
01306                         output_stream << "\t\t\tid " << id_string << "\n";
01307                         output_stream << "\t\t\ttime " << entry.mTime  << "\n";
01308                         output_stream << "\t\t\tflags " << entry.mFlags  << "\n";
01309                         output_stream << "\t\t}\n";
01310                 }
01311         }*/
01312 
01313         output_stream << "\t}\n";
01314         output_stream.flags(old_flags);
01315 
01316         return TRUE;
01317 }
01318 
01319 
01320 // Assumes we are in a block "ParcelData"
01321 void LLParcel::packMessage(LLMessageSystem* msg)
01322 {
01323     msg->addU32Fast( _PREHASH_ParcelFlags, getParcelFlags() );
01324     msg->addS32Fast( _PREHASH_SalePrice, getSalePrice() );
01325     msg->addStringFast( _PREHASH_Name,           getName() );
01326     msg->addStringFast( _PREHASH_Desc,           getDesc() );
01327     msg->addStringFast( _PREHASH_MusicURL,       getMusicURL() );
01328     msg->addStringFast( _PREHASH_MediaURL,       getMediaURL() );
01329     msg->addU8 ( "MediaAutoScale", getMediaAutoScale () );
01330     msg->addUUIDFast( _PREHASH_MediaID,  getMediaID() );
01331     msg->addUUIDFast( _PREHASH_GroupID,  getGroupID() );
01332     msg->addS32Fast( _PREHASH_PassPrice, mPassPrice );
01333     msg->addF32Fast( _PREHASH_PassHours, mPassHours );
01334     msg->addU8Fast(      _PREHASH_Category,      (U8)mCategory);
01335     msg->addUUIDFast( _PREHASH_AuthBuyerID, mAuthBuyerID);
01336     msg->addUUIDFast( _PREHASH_SnapshotID, mSnapshotID);
01337     msg->addVector3Fast(_PREHASH_UserLocation, mUserLocation);
01338     msg->addVector3Fast(_PREHASH_UserLookAt, mUserLookAt);
01339     msg->addU8Fast(      _PREHASH_LandingType, (U8)mLandingType);
01340 }
01341 
01342 // Assumes we are in a block "ParcelData"
01343 void LLParcel::packMessage(LLSD& msg)
01344 {
01345         msg["local_id"] = getLocalID();
01346         msg["parcel_flags"] = ll_sd_from_U32(getParcelFlags());
01347         msg["sale_price"] = getSalePrice();
01348         msg["name"] = getName();
01349         msg["description"] = getDesc();
01350         msg["music_url"] = getMusicURL();
01351         msg["media_url"] = getMediaURL();
01352         msg["media_desc"] = getMediaDesc();
01353         msg["media_type"] = getMediaType();
01354         msg["media_width"] = getMediaWidth();
01355         msg["media_height"] = getMediaHeight();
01356         msg["auto_scale"] = getMediaAutoScale();
01357         msg["media_loop"] = getMediaLoop();
01358         msg["obscure_media"] = getObscureMedia();
01359         msg["obscure_music"] = getObscureMusic();
01360         msg["media_id"] = getMediaID();
01361         msg["group_id"] = getGroupID();
01362         msg["pass_price"] = mPassPrice;
01363         msg["pass_hours"] = mPassHours;
01364         msg["category"] = (U8)mCategory;
01365         msg["auth_buyer_id"] = mAuthBuyerID;
01366         msg["snapshot_id"] = mSnapshotID;
01367         msg["snapshot_id"] = mSnapshotID;
01368         msg["user_location"] = ll_sd_from_vector3(mUserLocation);
01369         msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt);
01370         msg["landing_type"] = (U8)mLandingType;
01371 
01372 }
01373 
01374 
01375 void LLParcel::unpackMessage(LLMessageSystem* msg)
01376 {
01377     char buffer[256]; /* Flawfinder: ignore */
01378         
01379     msg->getU32Fast( _PREHASH_ParcelData,_PREHASH_ParcelFlags, mParcelFlags );
01380     msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_SalePrice, mSalePrice );
01381     msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Name, 256, buffer );
01382     setName(buffer);
01383     msg->getStringFast( _PREHASH_ParcelData,_PREHASH_Desc, 256, buffer );
01384     setDesc(buffer);
01385     msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MusicURL, 256, buffer );
01386     setMusicURL(buffer);
01387     msg->getStringFast( _PREHASH_ParcelData,_PREHASH_MediaURL, 256, buffer );
01388     setMediaURL(buffer);
01389     
01390     // non-optimized version
01391     msg->getU8 ( "ParcelData", "MediaAutoScale", mMediaAutoScale );
01392     
01393     msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_MediaID, mMediaID );
01394     msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_GroupID, mGroupID );
01395     msg->getS32Fast( _PREHASH_ParcelData,_PREHASH_PassPrice, mPassPrice );
01396     msg->getF32Fast( _PREHASH_ParcelData,_PREHASH_PassHours, mPassHours );
01397     U8 category;
01398     msg->getU8Fast(      _PREHASH_ParcelData,_PREHASH_Category, category);
01399     mCategory = (ECategory)category;
01400     msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_AuthBuyerID, mAuthBuyerID);
01401     msg->getUUIDFast( _PREHASH_ParcelData,_PREHASH_SnapshotID, mSnapshotID);
01402     msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLocation, mUserLocation);
01403     msg->getVector3Fast(_PREHASH_ParcelData,_PREHASH_UserLookAt, mUserLookAt);
01404     U8 landing_type;
01405     msg->getU8Fast(      _PREHASH_ParcelData,_PREHASH_LandingType, landing_type);
01406     mLandingType = (ELandingType)landing_type;
01407 
01408         // New Media Data
01409         // Note: the message has been converted to TCP
01410         if(msg->getNumberOfBlocks("MediaData") > 0)
01411         {
01412                 msg->getString("MediaData", "MediaDesc", 256, buffer);
01413                 setMediaDesc(buffer);
01414                 msg->getString("MediaData", "MediaType", 256, buffer);
01415                 setMediaType(buffer);
01416                 msg->getS32("MediaData", "MediaWidth", mMediaWidth);
01417                 msg->getS32("MediaData", "MediaHeight", mMediaHeight);
01418                 msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop );
01419                 msg->getU8 ( "MediaData", "ObscureMedia", mObscureMedia );
01420                 msg->getU8 ( "MediaData", "ObscureMusic", mObscureMusic );
01421         }
01422         else
01423         {
01424                 setMediaType("video/vnd.secondlife.qt.legacy");
01425                 setMediaDesc("No Description available without Server Upgrade");
01426                 mMediaLoop = true;
01427                 mObscureMedia = true;
01428                 mObscureMusic = true;
01429         }
01430 }
01431 
01432 void LLParcel::packAccessEntries(LLMessageSystem* msg,
01433                                                                  const std::map<LLUUID,LLAccessEntry>& list)
01434 {
01435     access_map_const_iterator cit = list.begin();
01436     access_map_const_iterator end = list.end();
01437     
01438     if (cit == end)
01439     {
01440         msg->nextBlockFast(_PREHASH_List);
01441         msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
01442         msg->addS32Fast(_PREHASH_Time, 0 );
01443         msg->addU32Fast(_PREHASH_Flags, 0 );
01444         return;
01445     }
01446     
01447     for ( ; cit != end; ++cit)
01448     {
01449         const LLAccessEntry& entry = (*cit).second;
01450         
01451         msg->nextBlockFast(_PREHASH_List);
01452         msg->addUUIDFast(_PREHASH_ID,    entry.mID );
01453         msg->addS32Fast(_PREHASH_Time,   entry.mTime );
01454         msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
01455     }
01456 }
01457 
01458 
01459 void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
01460                                    std::map<LLUUID,LLAccessEntry>* list)
01461 {
01462     LLUUID id;
01463     S32 time;
01464     U32 flags;
01465     
01466     S32 i;
01467     S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
01468     for (i = 0; i < count; i++)
01469     {
01470         msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
01471         msg->getS32Fast(                 _PREHASH_List, _PREHASH_Time, time, i);
01472         msg->getU32Fast(                 _PREHASH_List, _PREHASH_Flags, flags, i);
01473         
01474         if (id.notNull())
01475         {
01476             LLAccessEntry entry;
01477             entry.mID = id;
01478             entry.mTime = time;
01479             entry.mFlags = flags;
01480             
01481             (*list)[entry.mID] = entry;
01482         }
01483     }
01484 }
01485 
01486 
01487 void LLParcel::expirePasses(S32 now)
01488 {
01489     access_map_iterator itor = mAccessList.begin();
01490     while (itor != mAccessList.end())
01491     {
01492         const LLAccessEntry& entry = (*itor).second;
01493         
01494         if (entry.mTime != 0 && entry.mTime < now)
01495         {
01496             mAccessList.erase(itor++);
01497         }
01498         else
01499         {
01500             ++itor;
01501         }
01502     }
01503 }
01504 
01505 
01506 bool LLParcel::operator==(const LLParcel &rhs) const
01507 {
01508     if (mOwnerID != rhs.mOwnerID)
01509         return FALSE;
01510     
01511     if (mParcelFlags != rhs.mParcelFlags)
01512         return FALSE;
01513     
01514     if (mClaimDate != rhs.mClaimDate)
01515         return FALSE;
01516     
01517     if (mClaimPricePerMeter != rhs.mClaimPricePerMeter)
01518         return FALSE;
01519     
01520     if (mRentPricePerMeter != rhs.mRentPricePerMeter)
01521         return FALSE;
01522     
01523     return TRUE;
01524 }
01525 
01526 // Calculate rent
01527 S32 LLParcel::getTotalRent() const
01528 {
01529     return (S32)floor(0.5f + (F32)mArea * (F32)mRentPricePerMeter * (1.0f - mDiscountRate));
01530 }
01531 
01532 F32 LLParcel::getAdjustedRentPerMeter() const
01533 {
01534     return ((F32)mRentPricePerMeter * (1.0f - mDiscountRate));
01535 }
01536 
01537 LLVector3 LLParcel::getCenterpoint() const
01538 {
01539     LLVector3 rv;
01540     rv.mV[VX] = (getAABBMin().mV[VX] + getAABBMax().mV[VX]) * 0.5f;
01541     rv.mV[VY] = (getAABBMin().mV[VY] + getAABBMax().mV[VY]) * 0.5f;
01542     rv.mV[VZ] = 0.0f;
01543     return rv;
01544 }
01545 
01546 void LLParcel::extendAABB(const LLVector3& box_min, const LLVector3& box_max)
01547 {
01548     // Patch up min corner of AABB
01549     S32 i;
01550     for (i=0; i<3; i++)
01551     {
01552         if (box_min.mV[i] < mAABBMin.mV[i])
01553         {
01554             mAABBMin.mV[i] = box_min.mV[i];
01555         }
01556     }
01557     
01558     // Patch up max corner of AABB
01559     for (i=0; i<3; i++)
01560     {
01561         if (box_max.mV[i] > mAABBMax.mV[i])
01562         {
01563             mAABBMax.mV[i] = box_max.mV[i];
01564         }
01565     }
01566 }
01567 
01568 BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
01569 {
01570         if (mAccessList.size() >= (U32) PARCEL_MAX_ACCESS_LIST)
01571         {
01572                 return FALSE;
01573         }
01574         if (agent_id == getOwnerID())
01575         {
01576                 // Can't add owner to these lists
01577                 return FALSE;
01578         }
01579         access_map_iterator itor = mAccessList.begin();
01580         while (itor != mAccessList.end())
01581         {
01582                 const LLAccessEntry& entry = (*itor).second;
01583                 if (entry.mID == agent_id)
01584                 {
01585                         if (time == 0 || (entry.mTime != 0 && entry.mTime < time))
01586                         {
01587                                 mAccessList.erase(itor++);
01588                         }
01589                         else
01590                         {
01591                                 // existing one expires later
01592                                 return FALSE;
01593                         }
01594                 }
01595                 else
01596                 {
01597                         ++itor;
01598                 }
01599         }
01600     
01601     removeFromBanList(agent_id);
01602     
01603     LLAccessEntry new_entry;
01604     new_entry.mID                        = agent_id;
01605     new_entry.mTime      = time;
01606     new_entry.mFlags = 0x0;
01607     mAccessList[new_entry.mID] = new_entry;
01608     return TRUE;
01609 }
01610 
01611 BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
01612 {
01613         if (mBanList.size() >= (U32) PARCEL_MAX_ACCESS_LIST)
01614         {
01615                 // Not using ban list, so not a rational thing to do
01616                 return FALSE;
01617         }
01618         if (agent_id == getOwnerID())
01619         {
01620                 // Can't add owner to these lists
01621                 return FALSE;
01622         }
01623     
01624     access_map_iterator itor = mBanList.begin();
01625     while (itor != mBanList.end())
01626     {
01627         const LLAccessEntry& entry = (*itor).second;
01628         if (entry.mID == agent_id)
01629         {
01630             if (time == 0 || (entry.mTime != 0 && entry.mTime < time))
01631             {
01632                 mBanList.erase(itor++);
01633             }
01634             else
01635             {
01636                 // existing one expires later
01637                 return FALSE;
01638             }
01639         }
01640         else
01641         {
01642             ++itor;
01643         }
01644     }
01645     
01646     removeFromAccessList(agent_id);
01647     
01648     LLAccessEntry new_entry;
01649     new_entry.mID                        = agent_id;
01650     new_entry.mTime      = time;
01651     new_entry.mFlags = 0x0;
01652     mBanList[new_entry.mID] = new_entry;
01653     return TRUE;
01654 }
01655 
01656 BOOL remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
01657                               const LLUUID& agent_id)
01658 {
01659     BOOL removed = FALSE;
01660     access_map_iterator itor = list->begin();
01661     while (itor != list->end())
01662     {
01663         const LLAccessEntry& entry = (*itor).second;
01664         if (entry.mID == agent_id)
01665         {
01666             list->erase(itor++);
01667             removed = TRUE;
01668         }
01669         else
01670         {
01671             ++itor;
01672         }
01673     }
01674     return removed;
01675 }
01676 
01677 BOOL LLParcel::removeFromAccessList(const LLUUID& agent_id)
01678 {
01679     return remove_from_access_array(&mAccessList, agent_id);
01680 }
01681 
01682 BOOL LLParcel::removeFromBanList(const LLUUID& agent_id)
01683 {
01684     return remove_from_access_array(&mBanList, agent_id);
01685 }
01686 
01687 // static
01688 const char* LLParcel::getOwnershipStatusString(EOwnershipStatus status)
01689 {
01690     return ownership_status_to_string(status);
01691 }
01692 
01693 // static
01694 const char* LLParcel::getCategoryString(ECategory category)
01695 {
01696     return category_to_string(category);
01697 }
01698 
01699 // static
01700 const char* LLParcel::getCategoryUIString(ECategory category)
01701 {
01702     return category_to_ui_string(category);
01703 }
01704 
01705 // static
01706 LLParcel::ECategory LLParcel::getCategoryFromString(const char* string)
01707 {
01708     return category_string_to_category(string);
01709 }
01710 
01711 // static
01712 LLParcel::ECategory LLParcel::getCategoryFromUIString(const char* string)
01713 {
01714     return category_ui_string_to_category(string);
01715 }
01716 
01717 // static
01718 const char* LLParcel::getActionString(LLParcel::EAction action)
01719 {
01720     S32 index = 0;
01721     if((action >= 0) && (action < LLParcel::A_COUNT))
01722     {
01723         index = action;
01724     }
01725     else
01726     {
01727         index = A_COUNT;
01728     }
01729     return PARCEL_ACTION_STRING[index];
01730 }
01731 
01732 BOOL LLParcel::isSaleTimerExpired(const U64& time)
01733 {
01734     if (mSaleTimerExpires.getStarted() == FALSE)
01735     {
01736         return FALSE;
01737     }
01738     BOOL expired = mSaleTimerExpires.checkExpirationAndReset(0.0);
01739     if (expired)
01740     {
01741         mSaleTimerExpires.stop();
01742     }
01743     return expired;
01744 }
01745 
01746 
01747 void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
01748 {
01749         // TODO -- this and all Sale related methods need to move out of the LLParcel 
01750         // base class and into server-side-only LLSimParcel class
01751         setPreviousOwnerID(mOwnerID);
01752         setPreviouslyGroupOwned(mGroupOwned);
01753 
01754         mOwnerID = buyer_id;
01755         mGroupOwned = is_buyer_group;
01756         if(mGroupOwned)
01757         {
01758                 mGroupID = mOwnerID;
01759         }
01760         else
01761         {
01762                 mGroupID.setNull();
01763         }
01764         mSaleTimerExpires.start();
01765         mSaleTimerExpires.setTimerExpirySec(DEFAULT_USEC_SALE_TIMEOUT / SEC_TO_MICROSEC);
01766         mStatus = OS_LEASE_PENDING;
01767         mClaimDate = time(NULL);
01768         setAuctionID(0);
01769         // clear the autoreturn whenever land changes hands
01770         setCleanOtherTime(0);
01771 }
01772 
01773 void LLParcel::expireSale(U32& type, U8& flags, LLUUID& from_id, LLUUID& to_id)
01774 {
01775     mSaleTimerExpires.setTimerExpirySec(0.0);
01776     mSaleTimerExpires.stop();
01777     setPreviousOwnerID(LLUUID::null);
01778     setPreviouslyGroupOwned(FALSE);
01779     setSellWithObjects(FALSE);
01780     type = TRANS_LAND_RELEASE;
01781     mStatus = OS_NONE;
01782     flags = pack_transaction_flags(mGroupOwned, FALSE);
01783     mAuthBuyerID.setNull();
01784     from_id = mOwnerID;
01785     mOwnerID.setNull();
01786     to_id.setNull();
01787 }
01788 
01789 void LLParcel::completeSale(U32& type, U8& flags,
01790                             LLUUID& to_id)
01791 {
01792         mSaleTimerExpires.setTimerExpirySec(0.0);
01793         mSaleTimerExpires.stop();
01794         mStatus = OS_LEASED;
01795         type = TRANS_LAND_SALE;
01796         flags = pack_transaction_flags(mGroupOwned, mGroupOwned);
01797         to_id = mOwnerID;
01798         mAuthBuyerID.setNull();
01799 
01800         // Purchased parcels are assumed to no longer be for sale.
01801         // Otherwise someone can snipe the sale.
01802         setForSale(FALSE);
01803         setAuctionID(0);
01804 
01805         // Turn off show directory, since it's a recurring fee that
01806         // the buyer may not want.
01807         setParcelFlag(PF_SHOW_DIRECTORY, FALSE);
01808 
01809         //should be cleared on sale.
01810         mAccessList.clear();
01811         mBanList.clear();
01812 }
01813 
01814 void LLParcel::clearSale()
01815 {
01816         mSaleTimerExpires.setTimerExpirySec(0.0);
01817         mSaleTimerExpires.stop();
01818         if(isPublic())
01819         {
01820                 mStatus = OS_NONE;
01821         }
01822         else
01823         {
01824                 mStatus = OS_LEASED;
01825         }
01826         mAuthBuyerID.setNull();
01827         setForSale(FALSE);
01828         setAuctionID(0);
01829         setPreviousOwnerID(LLUUID::null);
01830         setPreviouslyGroupOwned(FALSE);
01831         setSellWithObjects(FALSE);
01832 }
01833 
01834 BOOL LLParcel::isPublic() const
01835 {
01836     return (mOwnerID.isNull());
01837 }
01838 
01839 BOOL LLParcel::isBuyerAuthorized(const LLUUID& buyer_id) const
01840 {
01841     if(mAuthBuyerID.isNull())
01842     {
01843         return TRUE;
01844     }
01845     return (mAuthBuyerID == buyer_id);
01846 }
01847 
01848 void LLParcel::clearParcel()
01849 {
01850         overrideParcelFlags(PF_DEFAULT);
01851         setName(NULL);
01852         setDesc(NULL);
01853         setMediaURL(NULL);
01854         setMediaType(NULL);
01855         setMediaID(LLUUID::null);
01856     setMediaDesc(NULL);
01857         setMediaAutoScale(0);
01858         setMediaLoop(TRUE);
01859         mObscureMedia = 1;
01860         mObscureMusic = 1;
01861         mMediaWidth = 0;
01862         mMediaHeight = 0;
01863         setMusicURL(NULL);
01864         setInEscrow(FALSE);
01865         setAuthorizedBuyerID(LLUUID::null);
01866         setCategory(C_NONE);
01867         setSnapshotID(LLUUID::null);
01868         setUserLocation(LLVector3::zero);
01869         setUserLookAt(LLVector3::x_axis);
01870         setLandingType(L_LANDING_POINT);
01871         setAuctionID(0);
01872         setGroupID(LLUUID::null);
01873         setPassPrice(0);
01874         setPassHours(0.f);
01875         mAccessList.clear();
01876         mBanList.clear();
01877         //mRenterList.reset();
01878 }
01879 
01880 void LLParcel::dump()
01881 {
01882     llinfos << "parcel " << mLocalID << " area " << mArea << llendl;
01883     llinfos << "         name <" << mName << ">" << llendl;
01884     llinfos << "         desc <" << mDesc << ">" << llendl;
01885 }
01886 
01887 const char* ownership_status_to_string(LLParcel::EOwnershipStatus status)
01888 {
01889     if(status >= 0 && status < LLParcel::OS_COUNT)
01890     {
01891         return PARCEL_OWNERSHIP_STATUS_STRING[status];
01892     }
01893     return "none";
01894 }
01895 
01896 LLParcel::EOwnershipStatus ownership_string_to_status(const char* s)
01897 {
01898     for(S32 i = 0; i < LLParcel::OS_COUNT; ++i)
01899     {
01900         if(0 == strcmp(s, PARCEL_OWNERSHIP_STATUS_STRING[i]))
01901         {
01902             return (LLParcel::EOwnershipStatus)i;
01903         }
01904     }
01905     return LLParcel::OS_NONE;
01906 }
01907 
01908 //const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action)
01909 //{
01910 // S32 index = 0;
01911 // if(action >= 0 && action < LLParcel::STEA_COUNT)
01912 // {
01913 //       index = action;
01914 // }
01915 // return PARCEL_SALE_TIMER_ACTION[index];
01916 //}
01917     
01918 //LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s)
01919 //{
01920 // for(S32 i = 0; i < LLParcel::STEA_COUNT; ++i)
01921 // {
01922 //       if(0 == strcmp(s, PARCEL_SALE_TIMER_ACTION[i]))
01923 //       {
01924 //               return (LLParcel::ESaleTimerExpireAction)i;
01925 //       }
01926 // }
01927 // return LLParcel::STEA_REVERT;
01928 //}
01929     
01930 const char* category_to_string(LLParcel::ECategory category)
01931 {
01932     S32 index = 0;
01933     if((category >= 0) && (category < LLParcel::C_COUNT))
01934     {
01935         index = category;
01936     }
01937     return PARCEL_CATEGORY_STRING[index];
01938 }
01939 
01940 const char* category_to_ui_string(LLParcel::ECategory category)
01941 {
01942     S32 index = 0;
01943     if((category >= 0) && (category < LLParcel::C_COUNT))
01944     {
01945         index = category;
01946     }
01947     else
01948     {
01949         // C_ANY = -1 , but the "Any" string is at the end of the list
01950         index = ((S32) LLParcel::C_COUNT);
01951     }
01952     return PARCEL_CATEGORY_UI_STRING[index];
01953 }
01954 
01955 LLParcel::ECategory category_string_to_category(const char* s)
01956 {
01957     for(S32 i = 0; i < LLParcel::C_COUNT; ++i)
01958     {
01959         if(0 == strcmp(s, PARCEL_CATEGORY_STRING[i]))
01960         {
01961             return (LLParcel::ECategory)i;
01962         }
01963     }
01964     llwarns << "Parcel category outside of possibilities " << s << llendl;
01965     return LLParcel::C_NONE;
01966 }
01967 
01968 LLParcel::ECategory category_ui_string_to_category(const char* s)
01969 {
01970     for(S32 i = 0; i < LLParcel::C_COUNT; ++i)
01971     {
01972         if(0 == strcmp(s, PARCEL_CATEGORY_UI_STRING[i]))
01973         {
01974             return (LLParcel::ECategory)i;
01975         }
01976     }
01977     // "Any" is a valid category for searches, and
01978     // is a distinct option from "None" and "Other"
01979     return LLParcel::C_ANY;
01980 }

Generated on Fri May 16 08:32:13 2008 for SecondLife by  doxygen 1.5.5