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
00059
00060
00061 static const char* PARCEL_CATEGORY_STRING[LLParcel::C_COUNT] =
00062 {
00063 "none",
00064 "linden",
00065 "adult",
00066 "arts",
00067 "store",
00068 "educational",
00069 "game",
00070 "gather",
00071 "newcomer",
00072 "park",
00073 "home",
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",
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
00112
00113 const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
00114
00115
00116
00117
00118 const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);
00119
00120
00121
00122
00123 const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);
00124
00125
00126
00127
00128 const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);
00129
00130
00131
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
00138
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
00163 LLParcel::~LLParcel()
00164 {
00165
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
00186 mLandingType = L_LANDING_POINT;
00187
00188
00189
00190 mStatus = OS_NONE;
00191 mCategory = C_NONE;
00192 mAuthBuyerID.setNull();
00193
00194
00195 mSaleTimerExpires.setTimerExpirySec(0);
00196 mSaleTimerExpires.stop();
00197 mGraceExtension = 0;
00198
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
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
00253
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
00289
00290 mName = name;
00291 LLStringFn::replace_nonprintable(mName, LL_UNKNOWN_CHAR);
00292 }
00293
00294 void LLParcel::setDesc(const LLString& desc)
00295 {
00296
00297
00298 mDesc = desc;
00299 mDesc = rawstr_to_utf8(mDesc);
00300 }
00301
00302 void LLParcel::setMusicURL(const LLString& url)
00303 {
00304 mMusicURL = url;
00305
00306
00307
00308
00309 LLStringFn::replace_nonprintable(mMusicURL, LL_UNKNOWN_CHAR);
00310 }
00311
00312 void LLParcel::setMediaURL(const LLString& url)
00313 {
00314 mMediaURL = url;
00315
00316
00317
00318
00319 LLStringFn::replace_nonprintable(mMediaURL, LL_UNKNOWN_CHAR);
00320 }
00321
00322 void LLParcel::setMediaDesc(const char* desc)
00323 {
00324
00325
00326 set_std_string(desc, mMediaDesc);
00327 mMediaDesc = rawstr_to_utf8(mMediaDesc);
00328 }
00329 void LLParcel::setMediaType(const char* type)
00330 {
00331
00332
00333 set_std_string(type, mMediaType);
00334 mMediaType = rawstr_to_utf8(mMediaType);
00335
00336
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
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
00379 return TRUE;
00380 }
00381 else if (isPublic())
00382 {
00383 return TRUE;
00384 }
00385 else if (agent_id == mOwnerID)
00386 {
00387
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
00408 return TRUE;
00409 }
00410 else if(OS_LEASED == mStatus)
00411 {
00412 if(agent_id == mOwnerID)
00413 {
00414
00415 return TRUE;
00416 }
00417 else
00418 {
00419
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
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
00471 if (isAgentBanned(agent_id))
00472 {
00473 return BA_BANNED;
00474 }
00475
00476
00477
00478
00479 if (agent_id == mOwnerID)
00480 {
00481 return BA_ALLOWED;
00482 }
00483
00484
00485
00486
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
00492 if (getParcelFlag(PF_USE_ACCESS_GROUP)
00493 && !mGroupID.isNull()
00494 && group_id == mGroupID
00495 && !passWithGroup)
00496 {
00497 return BA_ALLOWED;
00498 }
00499
00500
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
00512
00513 if ( !getParcelFlag(PF_USE_ACCESS_GROUP)
00514 && !getParcelFlag(PF_USE_ACCESS_LIST))
00515 {
00516
00517 if(getIsGroupOwned() && group_id == mGroupID)
00518 {
00519 return BA_ALLOWED;
00520 }
00521
00522
00523
00524 if(getParcelFlag(PF_DENY_ANONYMOUS) && !is_agent_identified && !is_agent_transacted)
00525 {
00526 return BA_NO_ACCESS_LEVEL;
00527 }
00528
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
00551
00552
00553 mDiscountRate = llclampf(rate);
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
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
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
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
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
00898
00899
00900
00901 else if ("require_identified" == keyword)
00902 {
00903
00904
00905 }
00906
00907
00908
00909
00910 else if ("require_transacted" == keyword)
00911 {
00912
00913
00914
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
00929
00930 }
00931 else if ("deny_transacted" == keyword)
00932 {
00933
00934
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
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 }
00981 else if ("pass_list" == keyword)
00982 {
00983
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
01004
01005
01006 F32 time_to_expire = 0.0f;
01007 if(mID.isNull())
01008 {
01009 mID.generate();
01010 mStatus = OS_LEASE_PENDING;
01011
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
01021 mRecordTransaction = TRUE;
01022 }
01023
01024
01025
01026
01027 if((0 == mGraceExtension)
01028 && (EXTEND_GRACE_IF_MORE_THAN_SEC < secs_until_revert))
01029 {
01030 const S32 NEW_CONVERSION_DATE = 1074538800;
01031 time_t now = time(NULL);
01032 secs_until_revert = (S32)(NEW_CONVERSION_DATE - now);
01033 time_to_expire = (F32)secs_until_revert;
01034 mGraceExtension = 1;
01035 }
01036
01037
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
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
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];
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
01171
01172
01173
01174 if(mSaleTimerExpires.getStarted())
01175 {
01176 S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60;
01177 output_stream << "\t\t revert_sale " << dt_sec << "\n";
01178
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
01224
01225
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
01246
01247
01248
01249
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
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 output_stream << "\t}\n";
01314 output_stream.flags(old_flags);
01315
01316 return TRUE;
01317 }
01318
01319
01320
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
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];
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
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
01409
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
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
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
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
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
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
01616 return FALSE;
01617 }
01618 if (agent_id == getOwnerID())
01619 {
01620
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
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
01688 const char* LLParcel::getOwnershipStatusString(EOwnershipStatus status)
01689 {
01690 return ownership_status_to_string(status);
01691 }
01692
01693
01694 const char* LLParcel::getCategoryString(ECategory category)
01695 {
01696 return category_to_string(category);
01697 }
01698
01699
01700 const char* LLParcel::getCategoryUIString(ECategory category)
01701 {
01702 return category_to_ui_string(category);
01703 }
01704
01705
01706 LLParcel::ECategory LLParcel::getCategoryFromString(const char* string)
01707 {
01708 return category_string_to_category(string);
01709 }
01710
01711
01712 LLParcel::ECategory LLParcel::getCategoryFromUIString(const char* string)
01713 {
01714 return category_ui_string_to_category(string);
01715 }
01716
01717
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
01750
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
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
01801
01802 setForSale(FALSE);
01803 setAuctionID(0);
01804
01805
01806
01807 setParcelFlag(PF_SHOW_DIRECTORY, FALSE);
01808
01809
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
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
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
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
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
01978
01979 return LLParcel::C_ANY;
01980 }