00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llviewerparcelmgr.h"
00035 
00036 
00037 #include "audioengine.h"
00038 #include "indra_constants.h"
00039 #include "llcachename.h"
00040 #include "llgl.h"
00041 #include "llmediaengine.h"
00042 #include "llparcel.h"
00043 #include "llsecondlifeurls.h"
00044 #include "message.h"
00045 
00046 
00047 #include "llagent.h"
00048 #include "llfloatergroupinfo.h"
00049 #include "llviewerwindow.h"
00050 #include "llviewercontrol.h"
00051 #include "llfirstuse.h"
00052 #include "llfloaterbuyland.h"
00053 #include "llfloatergroups.h"
00054 
00055 #include "llfloatersellland.h"
00056 #include "llfloatertools.h"
00057 #include "llnotify.h"
00058 #include "llresmgr.h"
00059 #include "llstatusbar.h"
00060 #include "llui.h"
00061 #include "llviewerimagelist.h"
00062 #include "llviewermenu.h"
00063 #include "llviewerparceloverlay.h"
00064 #include "llviewerregion.h"
00065 
00066 #include "llworld.h"
00067 #include "lloverlaybar.h"
00068 #include "roles_constants.h"
00069 
00070 const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
00071 
00072 
00073 
00074 LLViewerParcelMgr *gParcelMgr = NULL;
00075 
00076 U8* LLViewerParcelMgr::sPackedOverlay = NULL;
00077 
00078 LLUUID gCurrentMovieID = LLUUID::null;
00079 
00080 static LLParcelSelection* get_null_parcel_selection();
00081 template<> 
00082         const LLHandle<LLParcelSelection>::NullFunc 
00083                 LLHandle<LLParcelSelection>::sNullFunc = get_null_parcel_selection;
00084 
00085 
00086 
00087 void optionally_start_music(const LLString& music_url);
00088 void callback_start_music(S32 option, void* data);
00089 void optionally_prepare_video(const LLParcel *parcelp);
00090 void callback_prepare_video(S32 option, void* data);
00091 void prepare_video(const LLParcel *parcelp);
00092 void start_video(const LLParcel *parcelp);
00093 void stop_video();
00094 void callback_god_force_owner(S32 option, void* user_data);
00095 
00096 struct LLGodForceOwnerData
00097 {
00098         LLUUID mOwnerID;
00099         S32 mLocalID;
00100         LLHost mHost;
00101 
00102         LLGodForceOwnerData(
00103                 const LLUUID& owner_id,
00104                 S32 local_parcel_id,
00105                 const LLHost& host) :
00106                 mOwnerID(owner_id),
00107                 mLocalID(local_parcel_id),
00108                 mHost(host) {}
00109 };
00110 
00111 
00112 
00113 
00114 LLViewerParcelMgr::LLViewerParcelMgr()
00115 :       mSelected(FALSE),
00116         mWestSouth(),
00117         mEastNorth(),
00118         mSelectedDwell(0.f),
00119         mAgentParcelSequenceID(-1),
00120         mHoverWestSouth(),
00121         mHoverEastNorth(),
00122         mRenderCollision(FALSE),
00123         mRenderSelection(TRUE),
00124         mCollisionBanned(0),
00125         mCollisionTimer()
00126 {
00127         mCurrentParcel = new LLParcel();
00128         mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00129         mFloatingParcelSelection = new LLParcelSelection(mCurrentParcel);
00130 
00131         mAgentParcel = new LLParcel();
00132         mHoverParcel = new LLParcel();
00133         mCollisionParcel = new LLParcel();
00134 
00135         mParcelsPerEdge = S32(  REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
00136         mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
00137         resetSegments(mHighlightSegments);
00138 
00139         mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
00140         resetSegments(mCollisionSegments);
00141 
00142         mBlockedImageID.set(gViewerArt.getString("noentrylines.tga"));
00143         mBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE);
00144 
00145         mPassImageID.set(gViewerArt.getString("noentrypasslines.tga"));
00146         mPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE);
00147 
00148         S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;
00149         sPackedOverlay = new U8[overlay_size];
00150 
00151         mAgentParcelOverlay = new U8[mParcelsPerEdge * mParcelsPerEdge];
00152         S32 i;
00153         for (i = 0; i < mParcelsPerEdge * mParcelsPerEdge; i++)
00154         {
00155                 mAgentParcelOverlay[i] = 0;
00156         }
00157 }
00158 
00159 
00160 LLViewerParcelMgr::~LLViewerParcelMgr()
00161 {
00162         mCurrentParcelSelection->setParcel(NULL);
00163         mCurrentParcelSelection = NULL;
00164 
00165         mFloatingParcelSelection->setParcel(NULL);
00166         mFloatingParcelSelection = NULL;
00167 
00168         delete mCurrentParcel;
00169         mCurrentParcel = NULL;
00170 
00171         delete mAgentParcel;
00172         mAgentParcel = NULL;
00173 
00174         delete mCollisionParcel;
00175         mCollisionParcel = NULL;
00176 
00177         delete mHoverParcel;
00178         mHoverParcel = NULL;
00179 
00180         delete[] mHighlightSegments;
00181         mHighlightSegments = NULL;
00182 
00183         delete[] mCollisionSegments;
00184         mCollisionSegments = NULL;
00185 
00186         delete[] sPackedOverlay;
00187         sPackedOverlay = NULL;
00188 
00189         delete[] mAgentParcelOverlay;
00190         mAgentParcelOverlay = NULL;
00191 }
00192 
00193 void LLViewerParcelMgr::dump()
00194 {
00195         llinfos << "Parcel Manager Dump" << llendl;
00196         llinfos << "mSelected " << S32(mSelected) << llendl;
00197         llinfos << "Selected parcel: " << llendl;
00198         llinfos << mWestSouth << " to " << mEastNorth << llendl;
00199         mCurrentParcel->dump();
00200         llinfos << "banning " << mCurrentParcel->mBanList.size() << llendl;
00201         
00202         access_map_const_iterator cit = mCurrentParcel->mBanList.begin();
00203         access_map_const_iterator end = mCurrentParcel->mBanList.end();
00204         for ( ; cit != end; ++cit)
00205         {
00206                 llinfos << "ban id " << (*cit).first << llendl;
00207         }
00208         llinfos << "Hover parcel:" << llendl;
00209         mHoverParcel->dump();
00210         llinfos << "Agent parcel:" << llendl;
00211         mAgentParcel->dump();
00212 }
00213 
00214 
00215 LLViewerRegion* LLViewerParcelMgr::getSelectionRegion()
00216 {
00217         if (!gWorldp) return NULL;
00218 
00219         return gWorldp->getRegionFromPosGlobal( mWestSouth );
00220 }
00221 
00222 
00223 void LLViewerParcelMgr::getDisplayInfo(S32* area_out, S32* claim_out,
00224                                                                            S32* rent_out,
00225                                                                            BOOL* for_sale_out,
00226                                                                            F32* dwell_out)
00227 {
00228         S32 area = 0;
00229         S32 price = 0;
00230         S32 rent = 0;
00231         BOOL for_sale = FALSE;
00232         F32 dwell = 0.f;
00233 
00234         if (mSelected)
00235         {
00236                 if (mCurrentParcelSelection->mSelectedMultipleOwners)
00237                 {
00238                         area = mCurrentParcelSelection->getClaimableArea();
00239                 }
00240                 else
00241                 {
00242                         area = getSelectedArea();
00243                 }
00244 
00245                 if (mCurrentParcel->getForSale())
00246                 {
00247                         price = mCurrentParcel->getSalePrice();
00248                         for_sale = TRUE;
00249                 }
00250                 else
00251                 {
00252                         price = area * mCurrentParcel->getClaimPricePerMeter();
00253                         for_sale = FALSE;
00254                 }
00255 
00256                 rent = mCurrentParcel->getTotalRent();
00257 
00258                 dwell = mSelectedDwell;
00259         }
00260 
00261         *area_out = area;
00262         *claim_out = price;
00263         *rent_out = rent;
00264         *for_sale_out = for_sale;
00265         *dwell_out = dwell;
00266 }
00267 
00268 void LLViewerParcelMgr::getPrimInfo(S32 &sw_max, S32 &sw_total, S32 &max, S32 &total, S32 &owner, S32 &group, S32 &other, S32& selected, F32 &parcel_object_bonus, S32 &other_clean)
00269 {
00270         if (mSelected && mCurrentParcel)
00271         {
00272                 sw_max = mCurrentParcel->getSimWideMaxPrimCapacity();
00273                 sw_total = mCurrentParcel->getSimWidePrimCount();
00274                 max = llround(mCurrentParcel->getMaxPrimCapacity()*mCurrentParcel->getParcelPrimBonus());
00275                 total = mCurrentParcel->getPrimCount();
00276                 owner = mCurrentParcel->getOwnerPrimCount();
00277                 group = mCurrentParcel->getGroupPrimCount();
00278                 other = mCurrentParcel->getOtherPrimCount();
00279                 selected = mCurrentParcel->getSelectedPrimCount();
00280                 parcel_object_bonus = mCurrentParcel->getParcelPrimBonus();
00281                 other_clean = mCurrentParcel->getCleanOtherTime();
00282         }
00283 }
00284 
00285 S32 LLViewerParcelMgr::getSelectedArea() const
00286 {
00287         S32 rv = 0;
00288         if(mSelected && mCurrentParcel && mCurrentParcelSelection->mWholeParcelSelected)
00289         {
00290                 rv = mCurrentParcel->getArea();
00291         }
00292         else if(mSelected)
00293         {
00294                 F64 width = mEastNorth.mdV[VX] - mWestSouth.mdV[VX];
00295                 F64 height = mEastNorth.mdV[VY] - mWestSouth.mdV[VY];
00296                 F32 area = (F32)(width * height);
00297                 rv = llround(area);
00298         }
00299         return rv;
00300 }
00301 
00302 void LLViewerParcelMgr::resetSegments(U8* segments)
00303 {
00304         S32 i;
00305         S32 count = (mParcelsPerEdge+1)*(mParcelsPerEdge+1);
00306         for (i = 0; i < count; i++)
00307         {
00308                 segments[i] = 0x0;
00309         }
00310 }
00311 
00312 
00313 void LLViewerParcelMgr::writeHighlightSegments(F32 west, F32 south, F32 east,
00314                                                                                            F32 north)
00315 {
00316         S32 x, y;
00317         S32 min_x = llround( west / PARCEL_GRID_STEP_METERS );
00318         S32 max_x = llround( east / PARCEL_GRID_STEP_METERS );
00319         S32 min_y = llround( south / PARCEL_GRID_STEP_METERS );
00320         S32 max_y = llround( north / PARCEL_GRID_STEP_METERS );
00321 
00322         const S32 STRIDE = mParcelsPerEdge+1;
00323 
00324         
00325         y = min_y;
00326         for (x = min_x; x < max_x; x++)
00327         {
00328                 
00329                 
00330                 mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
00331         }
00332 
00333         
00334         x = min_x;
00335         for (y = min_y; y < max_y; y++)
00336         {
00337                 mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
00338         }
00339 
00340         
00341         
00342         y = max_y;
00343         for (x = min_x; x < max_x; x++)
00344         {
00345                 mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
00346         }
00347 
00348         
00349         x = max_x;
00350         for (y = min_y; y < max_y; y++)
00351         {
00352                 mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
00353         }
00354 }
00355 
00356 
00357 void LLViewerParcelMgr::writeSegmentsFromBitmap(U8* bitmap, U8* segments)
00358 {
00359         S32 x;
00360         S32 y;
00361         const S32 IN_STRIDE = mParcelsPerEdge;
00362         const S32 OUT_STRIDE = mParcelsPerEdge+1;
00363 
00364         for (y = 0; y < IN_STRIDE; y++)
00365         {
00366                 x = 0;
00367                 while( x < IN_STRIDE )
00368                 {
00369                         U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
00370 
00371                         S32 bit;
00372                         for (bit = 0; bit < 8; bit++)
00373                         {
00374                                 if (byte & (1 << bit) )
00375                                 {
00376                                         S32 out = x+y*OUT_STRIDE;
00377 
00378                                         
00379                                         segments[out]            ^= SOUTH_MASK;
00380                                         segments[out+OUT_STRIDE] ^= SOUTH_MASK;
00381 
00382                                         
00383                                         segments[out]   ^= WEST_MASK;
00384                                         segments[out+1] ^= WEST_MASK;
00385                                 }
00386                                 x++;
00387                         }
00388                 }
00389         }
00390 }
00391 
00392 
00393 void LLViewerParcelMgr::writeAgentParcelFromBitmap(U8* bitmap)
00394 {
00395         S32 x;
00396         S32 y;
00397         const S32 IN_STRIDE = mParcelsPerEdge;
00398 
00399         for (y = 0; y < IN_STRIDE; y++)
00400         {
00401                 x = 0;
00402                 while( x < IN_STRIDE )
00403                 {
00404                         U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
00405 
00406                         S32 bit;
00407                         for (bit = 0; bit < 8; bit++)
00408                         {
00409                                 if (byte & (1 << bit) )
00410                                 {
00411                                         mAgentParcelOverlay[x+y*IN_STRIDE] = 1;
00412                                 }
00413                                 else
00414                                 {
00415                                         mAgentParcelOverlay[x+y*IN_STRIDE] = 0;
00416                                 }
00417                                 x++;
00418                         }
00419                 }
00420         }
00421 }
00422 
00423 
00424 
00425 
00426 LLParcelSelectionHandle LLViewerParcelMgr::selectParcelAt(const LLVector3d& pos_global)
00427 {
00428         LLVector3d southwest = pos_global;
00429         LLVector3d northeast = pos_global;
00430 
00431         southwest -= LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
00432         southwest.mdV[VX] = llround( southwest.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
00433         southwest.mdV[VY] = llround( southwest.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
00434 
00435         northeast += LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
00436         northeast.mdV[VX] = llround( northeast.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
00437         northeast.mdV[VY] = llround( northeast.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
00438 
00439         
00440         return selectLand( southwest, northeast, TRUE );
00441 }
00442 
00443 
00444 
00445 LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle()
00446 {
00447         return selectLand(mWestSouth, mEastNorth, TRUE);
00448 }
00449 
00450 
00451 void LLViewerParcelMgr::selectCollisionParcel()
00452 {
00453         if (!gWorldp)
00454         {
00455                 return;
00456         }
00457 
00458         
00459         mWestSouth = gAgent.getRegion()->getOriginGlobal();
00460         mEastNorth = mWestSouth;
00461         mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0);
00462 
00463         
00464         LLMessageSystem *msg = gMessageSystem;
00465         msg->newMessageFast(_PREHASH_ParcelPropertiesRequestByID);
00466         msg->nextBlockFast(_PREHASH_AgentID);
00467         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00468         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00469         msg->nextBlockFast(_PREHASH_ParcelData);
00470         msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
00471         msg->addS32Fast(_PREHASH_LocalID, mCollisionParcel->getLocalID() );
00472         gAgent.sendReliableMessage();
00473 
00474         mRequestResult = PARCEL_RESULT_NO_DATA;
00475 
00476         
00477         mCurrentParcel->setName( mCollisionParcel->getName() );
00478         mCurrentParcel->setDesc( mCollisionParcel->getDesc() );
00479         mCurrentParcel->setPassPrice(mCollisionParcel->getPassPrice());
00480         mCurrentParcel->setPassHours(mCollisionParcel->getPassHours());
00481 
00482         
00483         resetSegments(mHighlightSegments);
00484 
00485         mFloatingParcelSelection->setParcel(mCurrentParcel);
00486         mCurrentParcelSelection->setParcel(NULL);
00487         mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00488 
00489         mSelected = TRUE;
00490         mCurrentParcelSelection->mWholeParcelSelected = TRUE;
00491         notifyObservers();
00492         return;
00493 }
00494 
00495 
00496 
00497 LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1, const LLVector3d &corner2,
00498                                                                    BOOL snap_selection)
00499 {
00500         if (!gWorldp)
00501         {
00502                 return NULL;
00503         }
00504 
00505         sanitize_corners( corner1, corner2, mWestSouth, mEastNorth );
00506 
00507         
00508         F32 delta_x = getSelectionWidth();
00509         if (delta_x * delta_x <= 1.f * 1.f)
00510         {
00511                 mSelected = FALSE;
00512                 notifyObservers();
00513                 return NULL;
00514         }
00515 
00516         
00517         F32 delta_y = getSelectionHeight();
00518         if (delta_y * delta_y <= 1.f * 1.f)
00519         {
00520                 mSelected = FALSE;
00521                 notifyObservers();
00522                 return NULL;
00523         }
00524 
00525         
00526         
00527         
00528         LLVector3d east_north_region_check( mEastNorth );
00529         east_north_region_check.mdV[VX] -= 0.5;
00530         east_north_region_check.mdV[VY] -= 0.5;
00531 
00532         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal(mWestSouth);
00533         LLViewerRegion *region_other = gWorldp->getRegionFromPosGlobal( east_north_region_check );
00534 
00535         if(!region)
00536         {
00537                 
00538                 mSelected = FALSE;
00539                 return NULL;
00540         }
00541 
00542         if (region != region_other)
00543         {
00544                 LLNotifyBox::showXml("CantSelectLandFromMultipleRegions");
00545                 mSelected = FALSE;
00546                 notifyObservers();
00547                 return NULL;
00548         }
00549 
00550         
00551         LLVector3 wsb_region = region->getPosRegionFromGlobal( mWestSouth );
00552         LLVector3 ent_region = region->getPosRegionFromGlobal( mEastNorth );
00553 
00554         
00555         LLMessageSystem *msg = gMessageSystem;
00556         msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
00557         msg->nextBlockFast(_PREHASH_AgentData);
00558         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00559         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00560         msg->nextBlockFast(_PREHASH_ParcelData);
00561         msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
00562         msg->addF32Fast(_PREHASH_West,  wsb_region.mV[VX] );
00563         msg->addF32Fast(_PREHASH_South, wsb_region.mV[VY] );
00564         msg->addF32Fast(_PREHASH_East,  ent_region.mV[VX] );
00565         msg->addF32Fast(_PREHASH_North, ent_region.mV[VY] );
00566         msg->addBOOL("SnapSelection", snap_selection);
00567         msg->sendReliable( region->getHost() );
00568 
00569         mRequestResult = PARCEL_RESULT_NO_DATA;
00570 
00571         
00572         resetSegments(mHighlightSegments);
00573 
00574         mFloatingParcelSelection->setParcel(mCurrentParcel);
00575         mCurrentParcelSelection->setParcel(NULL);
00576         mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00577 
00578         mSelected = TRUE;
00579         mCurrentParcelSelection->mWholeParcelSelected = snap_selection;
00580         notifyObservers();
00581         return mCurrentParcelSelection;
00582 }
00583 
00584 void LLViewerParcelMgr::deselectUnused()
00585 {
00586         
00587         if (mCurrentParcelSelection->getNumRefs() == 1 && mFloatingParcelSelection->getNumRefs() == 1)
00588         {
00589                 deselectLand();
00590         }
00591 }
00592 
00593 void LLViewerParcelMgr::deselectLand()
00594 {
00595         if (mSelected)
00596         {
00597                 mSelected = FALSE;
00598 
00599                 
00600                 mCurrentParcel->setLocalID(-1);
00601                 mCurrentParcel->mAccessList.clear();
00602                 mCurrentParcel->mBanList.clear();
00603                 
00604 
00605                 mSelectedDwell = 0.f;
00606 
00607                 notifyObservers();
00608 
00609                 
00610                 mCurrentParcelSelection->setParcel(NULL);
00611                 mFloatingParcelSelection->setParcel(NULL);
00612                 
00613                 mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00614         }
00615 }
00616 
00617 
00618 void LLViewerParcelMgr::addObserver(LLParcelObserver* observer)
00619 {
00620         mObservers.put(observer);
00621 }
00622 
00623 
00624 void LLViewerParcelMgr::removeObserver(LLParcelObserver* observer)
00625 {
00626         mObservers.removeObj(observer);
00627 }
00628 
00629 
00630 
00631 
00632 
00633 void LLViewerParcelMgr::notifyObservers()
00634 {
00635         LLDynamicArray<LLParcelObserver*> observers;
00636         S32 count = mObservers.count();
00637         S32 i;
00638         for(i = 0; i < count; ++i)
00639         {
00640                 observers.put(mObservers.get(i));
00641         }
00642         for(i = 0; i < count; ++i)
00643         {
00644                 observers.get(i)->changed();
00645         }
00646 }
00647 
00648 
00649 
00650 
00651 
00652 BOOL LLViewerParcelMgr::selectionEmpty() const
00653 {
00654         return !mSelected;
00655 }
00656 
00657 
00658 LLParcelSelectionHandle LLViewerParcelMgr::getParcelSelection() const
00659 {
00660         return mCurrentParcelSelection;
00661 }
00662 
00663 LLParcelSelectionHandle LLViewerParcelMgr::getFloatingParcelSelection() const
00664 {
00665         return mFloatingParcelSelection;
00666 }
00667 
00668 LLParcel *LLViewerParcelMgr::getAgentParcel() const
00669 {
00670         return mAgentParcel;
00671 }
00672 
00673 
00674 BOOL LLViewerParcelMgr::agentCanBuild() const
00675 {
00676         if (mAgentParcel)
00677         {
00678                 return (gAgent.isGodlike()
00679                                 || (mAgentParcel->allowModifyBy(
00680                                                 gAgent.getID(),
00681                                                 gAgent.getGroupID())));
00682         }
00683         else
00684         {
00685                 return gAgent.isGodlike();
00686         }
00687 }
00688 
00689 BOOL LLViewerParcelMgr::agentCanTakeDamage() const
00690 {
00691         return mAgentParcel->getAllowDamage();
00692 }
00693 
00694 BOOL LLViewerParcelMgr::agentCanFly() const
00695 {
00696         return TRUE;
00697 }
00698 
00699 F32 LLViewerParcelMgr::agentDrawDistance() const
00700 {
00701         return 512.f;
00702 }
00703 
00704 BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const
00705 {
00706         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal( pos_global );
00707         if (!region) return FALSE;
00708 
00709         LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00710         if (!overlay) return FALSE;
00711 
00712         LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00713 
00714         return overlay->isOwned( pos_region );
00715 }
00716 
00717 BOOL LLViewerParcelMgr::isOwnedSelfAt(const LLVector3d& pos_global) const
00718 {
00719         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal( pos_global );
00720         if (!region) return FALSE;
00721 
00722         LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00723         if (!overlay) return FALSE;
00724 
00725         LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00726 
00727         return overlay->isOwnedSelf( pos_region );
00728 }
00729 
00730 BOOL LLViewerParcelMgr::isOwnedOtherAt(const LLVector3d& pos_global) const
00731 {
00732         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal( pos_global );
00733         if (!region) return FALSE;
00734 
00735         LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00736         if (!overlay) return FALSE;
00737 
00738         LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00739 
00740         return overlay->isOwnedOther( pos_region );
00741 }
00742 
00743 BOOL LLViewerParcelMgr::isSoundLocal(const LLVector3d& pos_global) const
00744 {
00745         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal( pos_global );
00746         if (!region) return FALSE;
00747 
00748         LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00749         if (!overlay) return FALSE;
00750 
00751         LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00752 
00753         return overlay->isSoundLocal( pos_region );
00754 }
00755 
00756 BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const
00757 {
00758         BOOL in_agent_parcel = inAgentParcel(pos_global);
00759 
00760         if (in_agent_parcel)
00761         {
00762                 
00763                 return TRUE;
00764         }
00765         else
00766         {
00767                 if (gParcelMgr->getAgentParcel()->getSoundLocal())
00768                 {
00769                         
00770                         return FALSE;
00771                 }
00772                 else if (gParcelMgr->isSoundLocal(pos_global))
00773                 {
00774                         
00775                         return FALSE;
00776                 }
00777                 else
00778                 {
00779                         
00780                         return TRUE;
00781                 }
00782         }
00783 }
00784 
00785 
00786 BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const
00787 {
00788         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal(pos_global);
00789         if (region != gAgent.getRegion())
00790         {
00791                 
00792                 return FALSE;
00793         }
00794 
00795         LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global);
00796         S32 row =    S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);
00797         S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS);
00798 
00799         if (mAgentParcelOverlay[row*mParcelsPerEdge + column])
00800         {
00801                 return TRUE;
00802         }
00803         else
00804         {
00805                 return FALSE;
00806         }
00807 }
00808 
00809 
00810 LLParcel* LLViewerParcelMgr::getHoverParcel() const
00811 {
00812         if (mHoverRequestResult == PARCEL_RESULT_SUCCESS)
00813         {
00814                 return mHoverParcel;
00815         }
00816         else
00817         {
00818                 return NULL;
00819         }
00820 }
00821 
00822 
00823 LLParcel* LLViewerParcelMgr::getCollisionParcel() const
00824 {
00825         if (mRenderCollision)
00826         {
00827                 return mCollisionParcel;
00828         }
00829         else
00830         {
00831                 return NULL;
00832         }
00833 }
00834 
00835 
00836 
00837 
00838 
00839 void LLViewerParcelMgr::render()
00840 {
00841         if (mSelected && mRenderSelection)
00842         {
00843                 
00844                 
00845                 LLViewerRegion *regionp = gWorldp->getRegionFromPosGlobal( mWestSouth );
00846                 if (!regionp) return;
00847 
00848                 renderHighlightSegments(mHighlightSegments, regionp);
00849         }
00850 }
00851 
00852 
00853 void LLViewerParcelMgr::renderParcelCollision()
00854 {
00855         
00856         if (mCollisionTimer.getElapsedTimeF32() > PARCEL_COLLISION_DRAW_SECS)
00857         {
00858                 mRenderCollision = FALSE;
00859         }
00860 
00861         if (mRenderCollision)
00862         {
00863                 LLViewerRegion* regionp = gAgent.getRegion();
00864                 BOOL use_pass = mCollisionParcel->getParcelFlag(PF_USE_PASS_LIST);
00865                 renderCollisionSegments(mCollisionSegments, use_pass, regionp);
00866         }
00867 }
00868 
00869 
00870 void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags)
00871 {
00872         if (!mSelected)
00873         {
00874                 return;
00875         }
00876 
00877         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
00878         if (!region) return;
00879 
00880         LLMessageSystem *msg = gMessageSystem;
00881         
00882 
00883         if (flags & AL_BAN) 
00884         {
00885                 mCurrentParcel->mBanList.clear();
00886         }
00887         if (flags & AL_ACCESS) 
00888         {
00889                 mCurrentParcel->mAccessList.clear();
00890         }               
00891 
00892         
00893         msg->newMessageFast(_PREHASH_ParcelAccessListRequest);
00894         msg->nextBlockFast(_PREHASH_AgentData);
00895         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00896         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00897         msg->nextBlockFast(_PREHASH_Data);
00898         msg->addS32Fast(_PREHASH_SequenceID, 0);
00899         msg->addU32Fast(_PREHASH_Flags, flags);
00900         msg->addS32("LocalID", mCurrentParcel->getLocalID() );
00901         msg->sendReliable( region->getHost() );
00902 }
00903 
00904 
00905 void LLViewerParcelMgr::sendParcelDwellRequest()
00906 {
00907         if (!mSelected)
00908         {
00909                 return;
00910         }
00911 
00912         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
00913         if (!region) return;
00914 
00915         LLMessageSystem *msg = gMessageSystem;
00916 
00917         
00918         msg->newMessage("ParcelDwellRequest");
00919         msg->nextBlock("AgentData");
00920         msg->addUUID("AgentID", gAgent.getID() );
00921         msg->addUUID("SessionID", gAgent.getSessionID());
00922         msg->nextBlock("Data");
00923         msg->addS32("LocalID", mCurrentParcel->getLocalID());
00924         msg->addUUID("ParcelID", LLUUID::null); 
00925         msg->sendReliable( region->getHost() );
00926 }
00927 
00928 
00929 void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
00930 {
00931         if (!mSelected)
00932         {
00933                 gViewerWindow->alertXml("CannotSetLandOwnerNothingSelected");
00934                 return;
00935         }
00936 
00937         llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
00938 
00939         
00940         LLVector3d east_north_region_check( mEastNorth );
00941         east_north_region_check.mdV[VX] -= 0.5;
00942         east_north_region_check.mdV[VY] -= 0.5;
00943 
00944         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
00945         if (!region)
00946         {
00947                 
00948                 gViewerWindow->alertXml("CannotContentifyNoRegion");
00949                 return;
00950         }
00951 
00952         
00953         LLViewerRegion *region2 = gWorldp->getRegionFromPosGlobal( east_north_region_check );
00954         if (region != region2)
00955         {
00956                 gViewerWindow->alertXml("CannotSetLandOwnerMultipleRegions");
00957                 return;
00958         }
00959 
00960         llinfos << "Region " << region->getOriginGlobal() << llendl;
00961 
00962         LLGodForceOwnerData* data = new LLGodForceOwnerData(owner_id, mCurrentParcel->getLocalID(), region->getHost());
00963         if(mCurrentParcel->getAuctionID())
00964         {
00965                 gViewerWindow->alertXml("ForceOwnerAuctionWarning",
00966                         callback_god_force_owner,
00967                         (void*)data);
00968         }
00969         else
00970         {
00971                 callback_god_force_owner(0, (void*)data);
00972         }
00973 }
00974 
00975 void callback_god_force_owner(S32 option, void* user_data)
00976 {
00977         LLGodForceOwnerData* data = (LLGodForceOwnerData*)user_data;
00978         if(data && (0 == option))
00979         {
00980                 LLMessageSystem* msg = gMessageSystem;
00981                 msg->newMessage("ParcelGodForceOwner");
00982                 msg->nextBlock("AgentData");
00983                 msg->addUUID("AgentID", gAgent.getID());
00984                 msg->addUUID("SessionID", gAgent.getSessionID());
00985                 msg->nextBlock("Data");
00986                 msg->addUUID("OwnerID", data->mOwnerID);
00987                 msg->addS32( "LocalID", data->mLocalID);
00988                 msg->sendReliable(data->mHost);
00989         }
00990         delete data;
00991 }
00992 
00993 void LLViewerParcelMgr::sendParcelGodForceToContent()
00994 {
00995         if (!mSelected)
00996         {
00997                 gViewerWindow->alertXml("CannotContentifyNothingSelected");
00998                 return;
00999         }
01000         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01001         if (!region)
01002         {
01003                 gViewerWindow->alertXml("CannotContentifyNoRegion");
01004                 return;
01005         }
01006 
01007         LLMessageSystem* msg = gMessageSystem;
01008         msg->newMessage("ParcelGodMarkAsContent");
01009         msg->nextBlock("AgentData");
01010         msg->addUUID("AgentID", gAgent.getID());
01011         msg->addUUID("SessionID", gAgent.getSessionID());
01012         msg->nextBlock("ParcelData");
01013         msg->addS32("LocalID", mCurrentParcel->getLocalID());
01014         msg->sendReliable(region->getHost());
01015 }
01016 
01017 void LLViewerParcelMgr::sendParcelRelease()
01018 {
01019         if (!mSelected)
01020         {
01021         gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
01022                 return;
01023         }
01024 
01025         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01026         if (!region)
01027         {
01028                 gViewerWindow->alertXml("CannotReleaseLandNoRegion");
01029                 return;
01030         }
01031 
01032         
01033         
01034 
01035         LLMessageSystem* msg = gMessageSystem;
01036         msg->newMessage("ParcelRelease");
01037         msg->nextBlock("AgentData");
01038         msg->addUUID("AgentID", gAgent.getID() );
01039         msg->addUUID("SessionID", gAgent.getSessionID() );
01040         msg->nextBlock("Data");
01041         msg->addS32("LocalID", mCurrentParcel->getLocalID() );
01042         
01043         msg->sendReliable( region->getHost() );
01044 
01045         
01046         
01047         deselectLand();
01048 }
01049 
01050 class LLViewerParcelMgr::ParcelBuyInfo
01051 {
01052 public:
01053         LLUUID  mAgent;
01054         LLUUID  mSession;
01055         LLUUID  mGroup;
01056         BOOL    mIsGroupOwned;
01057         BOOL    mRemoveContribution;
01058         BOOL    mIsClaim;
01059         LLHost  mHost;
01060         
01061         
01062         S32             mParcelID;
01063         S32             mPrice;
01064         S32             mArea;
01065 
01066         
01067         F32             mWest;
01068         F32             mSouth;
01069         F32             mEast;
01070         F32             mNorth;
01071 };
01072 
01073 LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
01074         const LLUUID& agent_id,
01075         const LLUUID& session_id,
01076         const LLUUID& group_id,
01077         BOOL is_group_owned,
01078         BOOL is_claim,
01079         BOOL remove_contribution)
01080 {
01081         if (!mSelected || !mCurrentParcel)
01082         {
01083                 gViewerWindow->alertXml("CannotBuyLandNothingSelected");
01084                 return NULL;
01085         }
01086 
01087         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01088         if (!region)
01089         {
01090                 gViewerWindow->alertXml("CannotBuyLandNoRegion");
01091                 return NULL;
01092         }
01093         
01094         if (is_claim)
01095         {
01096                 llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
01097                 llinfos << "Region " << region->getOriginGlobal() << llendl;
01098 
01099                 
01100                 LLVector3d east_north_region_check( mEastNorth );
01101                 east_north_region_check.mdV[VX] -= 0.5;
01102                 east_north_region_check.mdV[VY] -= 0.5;
01103 
01104                 LLViewerRegion *region2 = gWorldp->getRegionFromPosGlobal( east_north_region_check );
01105 
01106                 if (region != region2)
01107                 {
01108                         gViewerWindow->alertXml("CantBuyLandAcrossMultipleRegions");
01109                         return NULL;
01110                 }
01111         }
01112         
01113         
01114         ParcelBuyInfo* info = new ParcelBuyInfo;
01115         
01116         info->mAgent = agent_id;
01117         info->mSession = session_id;
01118         info->mGroup = group_id;
01119         info->mIsGroupOwned = is_group_owned;
01120         info->mIsClaim = is_claim;
01121         info->mRemoveContribution = remove_contribution;
01122         info->mHost = region->getHost();
01123         info->mPrice = mCurrentParcel->getSalePrice();
01124         info->mArea = mCurrentParcel->getArea();
01125         
01126         if (!is_claim)
01127         {
01128                 info->mParcelID = mCurrentParcel->getLocalID();
01129         }
01130         else
01131         {
01132                 
01133                 LLVector3 west_south_bottom_region = region->getPosRegionFromGlobal( mWestSouth );
01134                 LLVector3 east_north_top_region = region->getPosRegionFromGlobal( mEastNorth );
01135                 
01136                 info->mWest             = west_south_bottom_region.mV[VX];
01137                 info->mSouth    = west_south_bottom_region.mV[VY];
01138                 info->mEast             = east_north_top_region.mV[VX];
01139                 info->mNorth    = east_north_top_region.mV[VY];
01140         }
01141         
01142         return info;
01143 }
01144 
01145 void LLViewerParcelMgr::sendParcelBuy(ParcelBuyInfo* info)
01146 {
01147         
01148         LLMessageSystem* msg = gMessageSystem;
01149         msg->newMessage(info->mIsClaim ? "ParcelClaim" : "ParcelBuy");
01150         msg->nextBlock("AgentData");
01151         msg->addUUID("AgentID", info->mAgent);
01152         msg->addUUID("SessionID", info->mSession);
01153         msg->nextBlock("Data");
01154         msg->addUUID("GroupID", info->mGroup);
01155         msg->addBOOL("IsGroupOwned", info->mIsGroupOwned);
01156         if (!info->mIsClaim)
01157         {
01158                 msg->addBOOL("RemoveContribution", info->mRemoveContribution);
01159                 msg->addS32("LocalID", info->mParcelID);
01160         }
01161         msg->addBOOL("Final", TRUE);    
01162         if (info->mIsClaim)
01163         {
01164                 msg->nextBlock("ParcelData");
01165                 msg->addF32("West",  info->mWest);
01166                 msg->addF32("South", info->mSouth);
01167                 msg->addF32("East",  info->mEast);
01168                 msg->addF32("North", info->mNorth);
01169         }
01170         else 
01171         {
01172                 msg->nextBlock("ParcelData");
01173                 msg->addS32("Price",info->mPrice);
01174                 msg->addS32("Area",info->mArea);
01175         }
01176         msg->sendReliable(info->mHost);
01177 }
01178 
01179 void LLViewerParcelMgr::deleteParcelBuy(ParcelBuyInfo*& info)
01180 {
01181         delete info;
01182         info = NULL;
01183 }
01184 
01185 void LLViewerParcelMgr::sendParcelDeed(const LLUUID& group_id)
01186 {
01187         if (!mSelected || !mCurrentParcel)
01188         {
01189                 gViewerWindow->alertXml("CannotDeedLandNothingSelected");
01190                 return;
01191         }
01192         if(group_id.isNull())
01193         {
01194                 gViewerWindow->alertXml("CannotDeedLandNoGroup");
01195                 return;
01196         }
01197         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01198         if (!region)
01199         {
01200                 gViewerWindow->alertXml("CannotDeedLandNoRegion");
01201                 return;
01202         }
01203 
01204         LLMessageSystem* msg = gMessageSystem;
01205         msg->newMessage("ParcelDeedToGroup");
01206         msg->nextBlock("AgentData");
01207         msg->addUUID("AgentID", gAgent.getID() );
01208         msg->addUUID("SessionID", gAgent.getSessionID() );
01209         msg->nextBlock("Data");
01210         msg->addUUID("GroupID", group_id );
01211         msg->addS32("LocalID", mCurrentParcel->getLocalID() );
01212         
01213         msg->sendReliable( region->getHost() );
01214 }
01215 
01216 
01217 
01218 
01219 
01220 
01221 
01222 
01223 
01224 
01225 
01226 
01227 
01228 
01229 
01230 
01231 
01232 
01233 
01234 
01235 
01236 
01237 
01238 
01239 
01240 
01241 
01242 
01243 
01244 
01245 
01246 
01247 
01248 
01249 
01250 
01251 
01252 
01253 
01254 
01255 const LLString& LLViewerParcelMgr::getAgentParcelName() const
01256 {
01257         return mAgentParcel->getName();
01258 }
01259 
01260 
01261 void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel)
01262 {
01263         if (!parcel) return;
01264 
01265         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01266         if (!region) return;
01267 
01268         LLMessageSystem *msg = gMessageSystem;
01269 
01270         msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate);
01271         msg->nextBlockFast(_PREHASH_AgentData);
01272         msg->addUUIDFast(_PREHASH_AgentID,      gAgent.getID() );
01273         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01274         msg->nextBlockFast(_PREHASH_ParcelData);
01275         msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
01276 
01277         U32 flags = 0x0;
01278         
01279         flags |= 0x01;
01280         msg->addU32("Flags", flags);
01281 
01282         parcel->packMessage(msg);
01283 
01284         msg->sendReliable( region->getHost() );
01285 }
01286 
01287 
01288 void LLViewerParcelMgr::requestHoverParcelProperties(const LLVector3d& pos)
01289 {
01290         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( pos );
01291         if (!region)
01292         {
01293                 return;
01294         }
01295 
01296         
01297         
01298         
01299         LLVector3 wsb_region = region->getPosRegionFromGlobal( pos );
01300 
01301         F32 west  = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS );
01302         F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS );
01303 
01304         F32 east  = west  + PARCEL_GRID_STEP_METERS;
01305         F32 north = south + PARCEL_GRID_STEP_METERS;
01306 
01307         
01308         LLMessageSystem *msg = gMessageSystem;
01309         msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
01310         msg->nextBlockFast(_PREHASH_AgentData);
01311         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01312         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
01313         msg->nextBlockFast(_PREHASH_ParcelData);
01314         msg->addS32Fast(_PREHASH_SequenceID,    HOVERED_PARCEL_SEQ_ID );
01315         msg->addF32Fast(_PREHASH_West,                  west );
01316         msg->addF32Fast(_PREHASH_South,                 south );
01317         msg->addF32Fast(_PREHASH_East,                  east );
01318         msg->addF32Fast(_PREHASH_North,                 north );
01319         msg->addBOOL("SnapSelection",                   FALSE );
01320         msg->sendReliable( region->getHost() );
01321 
01322         mHoverRequestResult = PARCEL_RESULT_NO_DATA;
01323 }
01324 
01325 
01326 
01327 void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
01328 {
01329         if (gNoRender)
01330         {
01331                 return;
01332         }
01333 
01334         
01335         S32 packed_overlay_size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Data);
01336 
01337         if (packed_overlay_size == 0)
01338         {
01339                 llwarns << "Overlay size 0" << llendl;
01340                 return;
01341         }
01342 
01343         S32 parcels_per_edge = gParcelMgr->mParcelsPerEdge;
01344         S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
01345         if (packed_overlay_size != expected_size)
01346         {
01347                 llwarns << "Got parcel overlay size " << packed_overlay_size
01348                         << " expecting " << expected_size << llendl;
01349                 return;
01350         }
01351 
01352         S32 sequence_id;
01353         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id);
01354         msg->getBinaryDataFast(
01355                         _PREHASH_ParcelData,
01356                         _PREHASH_Data,
01357                         sPackedOverlay,
01358                         expected_size);
01359 
01360         LLHost host = msg->getSender();
01361         LLViewerRegion *region = gWorldp->getRegion(host);
01362         if (region)
01363         {
01364                 region->mParcelOverlay->uncompressLandOverlay( sequence_id, sPackedOverlay );
01365         }
01366 }
01367 
01368 
01369 
01370 void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
01371 {
01372         S32             request_result;
01373         S32             sequence_id;
01374         BOOL    snap_selection = FALSE;
01375         S32             self_count = 0;
01376         S32             other_count = 0;
01377         S32             public_count = 0;
01378         S32             local_id;
01379         LLUUID  owner_id;
01380         BOOL    is_group_owned;
01381         U32 auction_id = 0;
01382         S32             claim_price_per_meter = 0;
01383         S32             rent_price_per_meter = 0;
01384         S32             claim_date = 0;
01385         LLVector3       aabb_min;
01386         LLVector3       aabb_max;
01387         S32             area = 0;
01388         S32             sw_max_prims = 0;
01389         S32             sw_total_prims = 0;
01390         
01391         U8 status = 0;
01392         S32             max_prims = 0;
01393         S32             total_prims = 0;
01394         S32             owner_prims = 0;
01395         S32             group_prims = 0;
01396         S32             other_prims = 0;
01397         S32             selected_prims = 0;
01398         F32             parcel_prim_bonus = 1.f;
01399         BOOL    region_push_override = false;
01400         BOOL    region_deny_anonymous_override = false;
01401         BOOL    region_deny_identified_override = false;
01402         BOOL    region_deny_transacted_override = false;
01403 
01404         S32             other_clean_time = 0;
01405 
01406         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
01407         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
01408 
01409         if (request_result == PARCEL_RESULT_NO_DATA)
01410         {
01411                 
01412                 llinfos << "no valid parcel data" << llendl;
01413                 return;
01414         }
01415 
01416         
01417         LLParcel* parcel = NULL;
01418         if (sequence_id == SELECTED_PARCEL_SEQ_ID)
01419         {
01420                 
01421                 gParcelMgr->mRequestResult = PARCEL_RESULT_SUCCESS;
01422                 parcel = gParcelMgr->mCurrentParcel;
01423         }
01424         else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
01425         {
01426                 gParcelMgr->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
01427                 parcel = gParcelMgr->mHoverParcel;
01428         }
01429         else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
01430                          sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
01431                          sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01432         {
01433                 gParcelMgr->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
01434                 parcel = gParcelMgr->mCollisionParcel;
01435         }
01436         else if (sequence_id == 0 || sequence_id > gParcelMgr->mAgentParcelSequenceID)
01437         {
01438                 
01439                 gParcelMgr->mAgentParcelSequenceID = sequence_id;
01440                 parcel = gParcelMgr->mAgentParcel;
01441         }
01442         else
01443         {
01444                 llinfos << "out of order agent parcel sequence id " << sequence_id
01445                         << " last good " << gParcelMgr->mAgentParcelSequenceID
01446                         << llendl;
01447                 return;
01448         }
01449 
01450         msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
01451         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
01452         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
01453         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
01454         msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_LocalID,         local_id );
01455         msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID,         owner_id);
01456         msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
01457         msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
01458         msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate,       claim_date);
01459         msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice,      claim_price_per_meter);
01460         msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice,       rent_price_per_meter);
01461         msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
01462         msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
01463         msg->getS32Fast(        _PREHASH_ParcelData, _PREHASH_Area, area );
01464         
01465         msg->getU8("ParcelData", "Status", status);
01466         msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims );
01467         msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims );
01468         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims );
01469         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims );
01470         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims );
01471         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims );
01472         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims );
01473         msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims );
01474         msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus );
01475         msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override );
01476         msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override );
01477         msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override );
01478         msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override );
01479 
01480         msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
01481 
01482         
01483         if (parcel)
01484         {
01485                 parcel->init(owner_id,
01486                         FALSE, FALSE, FALSE,
01487                         claim_date, claim_price_per_meter, rent_price_per_meter,
01488                         area, other_prims, parcel_prim_bonus, is_group_owned);
01489                 parcel->setLocalID(local_id);
01490                 parcel->setAABBMin(aabb_min);
01491                 parcel->setAABBMax(aabb_max);
01492 
01493                 parcel->setAuctionID(auction_id);
01494                 parcel->setOwnershipStatus((LLParcel::EOwnershipStatus)status);
01495 
01496                 parcel->setSimWideMaxPrimCapacity(sw_max_prims);
01497                 parcel->setSimWidePrimCount(sw_total_prims);
01498                 parcel->setMaxPrimCapacity(max_prims);
01499                 parcel->setOwnerPrimCount(owner_prims);
01500                 parcel->setGroupPrimCount(group_prims);
01501                 parcel->setOtherPrimCount(other_prims);
01502                 parcel->setSelectedPrimCount(selected_prims);
01503                 parcel->setParcelPrimBonus(parcel_prim_bonus);
01504 
01505                 parcel->setCleanOtherTime(other_clean_time);
01506                 parcel->setRegionPushOverride(region_push_override);
01507                 parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
01508                 parcel->setRegionDenyIdentifiedOverride(region_deny_identified_override);
01509                 parcel->setRegionDenyTransactedOverride(region_deny_transacted_override);
01510                 parcel->unpackMessage(msg);
01511 
01512                 if (parcel == gParcelMgr->mAgentParcel)
01513                 {
01514                         S32 bitmap_size =       gParcelMgr->mParcelsPerEdge
01515                                                                 * gParcelMgr->mParcelsPerEdge
01516                                                                 / 8;
01517                         U8* bitmap = new U8[ bitmap_size ];
01518                         msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01519 
01520                         gParcelMgr->writeAgentParcelFromBitmap(bitmap);
01521                         delete[] bitmap;
01522                 }
01523         }
01524 
01525         
01526         if (sequence_id == SELECTED_PARCEL_SEQ_ID)
01527         {
01528                 
01529                 gParcelMgr->mCurrentParcelSelection->mSelectedSelfCount = self_count;
01530                 gParcelMgr->mCurrentParcelSelection->mSelectedOtherCount = other_count;
01531                 gParcelMgr->mCurrentParcelSelection->mSelectedPublicCount = public_count;
01532 
01533                 gParcelMgr->mCurrentParcelSelection->mSelectedMultipleOwners =
01534                                                         (request_result == PARCEL_RESULT_MULTIPLE);
01535 
01536                 
01537                 LLViewerRegion *region = gWorldp->getRegion( msg->getSender() );
01538                 if (region)
01539                 {
01540                         if (!snap_selection)
01541                         {
01542                                 
01543                                 
01544                                 LLVector3 west_south = region->getPosRegionFromGlobal(gParcelMgr->mWestSouth);
01545                                 LLVector3 east_north = region->getPosRegionFromGlobal(gParcelMgr->mEastNorth);
01546 
01547                                 gParcelMgr->resetSegments(gParcelMgr->mHighlightSegments);
01548                                 gParcelMgr->writeHighlightSegments(
01549                                                                 west_south.mV[VX],
01550                                                                 west_south.mV[VY],
01551                                                                 east_north.mV[VX],
01552                                                                 east_north.mV[VY] );
01553                                 gParcelMgr->mCurrentParcelSelection->mWholeParcelSelected = FALSE;
01554                         }
01555                         else if (0 == local_id)
01556                         {
01557                                 
01558                                 gParcelMgr->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
01559                                 gParcelMgr->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
01560 
01561                                 gParcelMgr->resetSegments(gParcelMgr->mHighlightSegments);
01562                                 gParcelMgr->writeHighlightSegments(
01563                                                                 aabb_min.mV[VX],
01564                                                                 aabb_min.mV[VY],
01565                                                                 aabb_max.mV[VX],
01566                                                                 aabb_max.mV[VY] );
01567                                 gParcelMgr->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
01568                         }
01569                         else
01570                         {
01571                                 gParcelMgr->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
01572                                 gParcelMgr->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
01573 
01574                                 
01575                                 S32 bitmap_size =       gParcelMgr->mParcelsPerEdge
01576                                                                         * gParcelMgr->mParcelsPerEdge
01577                                                                         / 8;
01578                                 U8* bitmap = new U8[ bitmap_size ];
01579                                 msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01580 
01581                                 gParcelMgr->resetSegments(gParcelMgr->mHighlightSegments);
01582                                 gParcelMgr->writeSegmentsFromBitmap( bitmap, gParcelMgr->mHighlightSegments );
01583 
01584                                 delete[] bitmap;
01585                                 bitmap = NULL;
01586 
01587                                 gParcelMgr->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
01588                         }
01589 
01590                         
01591                         gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
01592 
01593                         
01594                         gParcelMgr->mSelectedDwell = 0.f;
01595                         if (0 != local_id)
01596                         {
01597                                 gParcelMgr->sendParcelDwellRequest();
01598                         }
01599 
01600                         gParcelMgr->mSelected = TRUE;
01601                         gParcelMgr->notifyObservers();
01602                 }
01603         }
01604         else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
01605                          sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID  ||
01606                          sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01607         {
01608                 
01609                 gParcelMgr->mRenderCollision = TRUE;
01610                 gParcelMgr->mCollisionTimer.reset();
01611 
01612                 
01613                 if (sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01614                 {
01615                         gParcelMgr->mCollisionBanned = BA_BANNED;
01616                 }
01617                 else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID)
01618                 {
01619                         gParcelMgr->mCollisionBanned = BA_NOT_IN_GROUP;
01620                 }
01621                 else 
01622                 {
01623                         gParcelMgr->mCollisionBanned = BA_NOT_ON_LIST;
01624 
01625                 }
01626 
01627                 S32 bitmap_size =       gParcelMgr->mParcelsPerEdge
01628                                                         * gParcelMgr->mParcelsPerEdge
01629                                                         / 8;
01630                 U8* bitmap = new U8[ bitmap_size ];
01631                 msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01632 
01633                 gParcelMgr->resetSegments(gParcelMgr->mCollisionSegments);
01634                 gParcelMgr->writeSegmentsFromBitmap( bitmap, gParcelMgr->mCollisionSegments );
01635 
01636                 delete[] bitmap;
01637                 bitmap = NULL;
01638 
01639         }
01640         else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
01641         {
01642                 LLViewerRegion *region = gWorldp->getRegion( msg->getSender() );
01643                 if (region)
01644                 {
01645                         gParcelMgr->mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min );
01646                         gParcelMgr->mHoverEastNorth = region->getPosGlobalFromRegion( aabb_max );
01647                 }
01648                 else
01649                 {
01650                         gParcelMgr->mHoverWestSouth.clearVec();
01651                         gParcelMgr->mHoverEastNorth.clearVec();
01652                 }
01653         }
01654         else
01655         {
01656                 
01657                 BOOL new_parcel = parcel ? FALSE : TRUE;
01658                 if (parcel)
01659                 {
01660                         S32 parcelid = parcel->getLocalID();
01661                         U64 regionid = gAgent.getRegion()->getHandle();
01662                         if (parcelid != gParcelMgr->mMediaParcelId || regionid != gParcelMgr->mMediaRegionId)
01663                         {
01664                                 gParcelMgr->mMediaParcelId = parcelid;
01665                                 gParcelMgr->mMediaRegionId = regionid;
01666                                 new_parcel = TRUE;
01667                         }
01668                 }
01669                 
01670                 if (gAudiop)
01671                 {
01672                         if (parcel)
01673                         {
01674                                 LLString music_url_raw = parcel->getMusicURL();
01675 
01676                                 
01677                                 LLString music_url = music_url_raw;
01678                                 LLString::trim(music_url);
01679 
01680                                 
01681                                 
01682                                 
01683                                 const char* stream_url = gAudiop->getInternetStreamURL();
01684 
01685                                 if (music_url.empty() || music_url != stream_url)
01686                                 {
01687                                         
01688                                         gAudiop->stopInternetStream();
01689 
01690                                         
01691                                         if (music_url.size() > 12)
01692                                         {
01693                                                 if (music_url.substr(0,7) == "http://")
01694                                                 {
01695                                                         optionally_start_music(music_url);
01696                                                 }
01697                                         }
01698                                         else if (gAudiop->getInternetStreamURL()[0])
01699                                         {
01700                                                 llinfos << "Stopping parcel music" << llendl;
01701                                                 gAudiop->startInternetStream(NULL);
01702                                         }
01703                                 }
01704                         }
01705                         else
01706                         {
01707                                 
01708                                 gAudiop->stopInternetStream();
01709                         }
01710                 }
01711 
01712                 
01713                 if (LLMediaEngine::getInstance ()->isAvailable ())
01714                 {
01715                         
01716                         if (parcel)
01717                         {
01718                                 
01719                                 std::string mediaUrl = std::string ( parcel->getMediaURL () );
01720                                 LLString::trim(mediaUrl);
01721 
01722                                 
01723                                 LLMediaEngine* me = LLMediaEngine::getInstance();
01724                                 if (  ( me->getUrl () != mediaUrl )
01725                                         || ( me->getImageUUID () != parcel->getMediaID () ) 
01726                                         || ( me->isAutoScaled () != parcel->getMediaAutoScale () ) )
01727                                 {
01728                                         BOOL video_was_playing = FALSE;
01729                                         LLMediaBase* renderer = me->getMediaRenderer();
01730                                         if (renderer && (renderer->isPlaying() || renderer->isLooping()))
01731                                         {
01732                                                 video_was_playing = TRUE;
01733                                         }
01734 
01735                                         stop_video();
01736 
01737                                         if ( !mediaUrl.empty () )
01738                                         {
01739                                                 
01740                                                 
01741                                                 if (!new_parcel
01742                                                         && gSavedSettings.getBOOL("AudioStreamingVideo")
01743                                                         && video_was_playing)
01744                                                 {
01745                                                         start_video(parcel);
01746                                                 }
01747                                                 else
01748                                                 {
01749                                                         
01750                                                         optionally_prepare_video(parcel);
01751                                                 }
01752                                         }
01753                                 }
01754                         }
01755                         else
01756                         {
01757                                 stop_video();
01758                         }
01759                 }
01760                 else
01761                 {
01762                         
01763                         if (parcel)
01764                         {
01765                                 std::string mediaUrl = std::string ( parcel->getMediaURL () );
01766                                 if (!mediaUrl.empty ())
01767                                 {
01768                                         if (gSavedSettings.getWarning("QuickTimeInstalled"))
01769                                         {
01770                                                 gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
01771 
01772                                                 LLNotifyBox::showXml("NoQuickTime" );
01773                                         };
01774                                 }
01775                         }
01776                 }
01777 
01778         };
01779 }
01780 
01781 void optionally_start_music(const LLString& music_url)
01782 {
01783         if (gSavedSettings.getWarning("FirstStreamingMusic"))
01784         {
01785                 std::string* newstring = new std::string(music_url);
01786                 gViewerWindow->alertXml("ParcelCanPlayMusic",
01787                         callback_start_music,
01788                         (void*)newstring);
01789 
01790         }
01791         else if (gSavedSettings.getBOOL("AudioStreamingMusic"))
01792         {
01793                 
01794                 
01795 
01796                 
01797                 
01798                 if ( gOverlayBar && gOverlayBar->musicPlaying() )
01799                 {
01800                         LLOverlayBar::musicPlay(NULL);
01801                 }
01802         }
01803 }
01804 
01805 
01806 void callback_start_music(S32 option, void* data)
01807 {
01808         std::string* music_url = (std::string*)data;
01809 
01810         if (0 == option)
01811         {
01812                 gSavedSettings.setBOOL("AudioStreamingMusic", TRUE);
01813                 llinfos << "Starting first parcel music " << music_url << llendl;
01814                 LLOverlayBar::musicPlay(NULL);
01815         }
01816         else
01817         {
01818                 gSavedSettings.setBOOL("AudioStreamingMusic", FALSE);
01819         }
01820 
01821         gSavedSettings.setWarning("FirstStreamingMusic", FALSE);
01822 
01823         delete music_url;
01824         music_url = NULL;
01825 }
01826 
01827 void prepare_video(const LLParcel *parcel)
01828 {
01829         std::string mediaUrl;
01830         if (parcel->getParcelFlag(PF_URL_RAW_HTML))
01831         {
01832                 mediaUrl = std::string("data:");
01833                 mediaUrl.append(parcel->getMediaURL());
01834         }
01835         else
01836         {
01837                 mediaUrl = std::string ( parcel->getMediaURL () );
01838         }
01839         LLMediaEngine::getInstance ()->setUrl ( mediaUrl );
01840         LLMediaEngine::getInstance ()->setImageUUID ( parcel->getMediaID () );
01841         LLMediaEngine::getInstance ()->setAutoScaled ( parcel->getMediaAutoScale () ? TRUE : FALSE );  
01842 }
01843 
01844 void start_video(const LLParcel *parcel)
01845 {
01846         prepare_video(parcel);
01847         std::string path( "" );
01848         LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, path);
01849 }
01850 
01851 void stop_video()
01852 {
01853         
01854         LLMediaEngine::getInstance ()->stop ();
01855         if (gOverlayBar)
01856         {
01857                 gOverlayBar->refresh ();
01858         }
01859 
01860         if (LLMediaEngine::getInstance ()->isLoaded())
01861         {
01862                 LLMediaEngine::getInstance ()->unload ();
01863 
01864                 gImageList.updateMovieImage(LLUUID::null, FALSE);
01865                 gCurrentMovieID.setNull();
01866         }
01867 
01868         LLMediaEngine::getInstance ()->setUrl ( "" );
01869         LLMediaEngine::getInstance ()->setImageUUID ( LLUUID::null );
01870         
01871 }
01872 
01873 void optionally_prepare_video(const LLParcel *parcelp)
01874 {
01875         if (gSavedSettings.getWarning("FirstStreamingVideo"))
01876         {
01877                 gViewerWindow->alertXml("ParcelCanPlayMedia",
01878                         callback_prepare_video,
01879                         (void*)parcelp);
01880         }
01881         else
01882         {
01883                 llinfos << "Entering parcel " << parcelp->getLocalID() << " with video " <<  parcelp->getMediaURL() << llendl;
01884                 prepare_video(parcelp);
01885         }
01886 }
01887 
01888 
01889 void callback_prepare_video(S32 option, void* data)
01890 {
01891         const LLParcel *parcelp = (const LLParcel *)data;
01892 
01893         if (0 == option)
01894         {
01895                 gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
01896                 llinfos << "Starting parcel video " <<  parcelp->getMediaURL() << " on parcel " << parcelp->getLocalID() << llendl;
01897                 gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media);
01898                 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update );
01899                 prepare_video(parcelp);
01900         }
01901         else
01902         {
01903                 gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback);
01904                 gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback );
01905                 gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
01906         }
01907 
01908         gSavedSettings.setWarning("FirstStreamingVideo", FALSE);
01909 }
01910 
01911 
01912 void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user)
01913 {
01914         LLUUID agent_id;
01915         S32 sequence_id = 0;
01916         U32 message_flags = 0x0;
01917         S32 parcel_id = -1;
01918 
01919         msg->getUUIDFast(_PREHASH_Data, _PREHASH_AgentID, agent_id);
01920         msg->getS32Fast( _PREHASH_Data, _PREHASH_SequenceID, sequence_id );     
01921         msg->getU32Fast( _PREHASH_Data, _PREHASH_Flags, message_flags);
01922         msg->getS32Fast( _PREHASH_Data, _PREHASH_LocalID, parcel_id);
01923 
01924         LLParcel* parcel = gParcelMgr->mCurrentParcel;
01925         if (!parcel) return;
01926 
01927         if (parcel_id != parcel->getLocalID())
01928         {
01929                 llwarns << "processParcelAccessListReply for parcel " << parcel_id
01930                         << " which isn't the selected parcel " << parcel->getLocalID()<< llendl;
01931                 return;
01932         }
01933 
01934         if (message_flags & AL_ACCESS)
01935         {
01936                 parcel->unpackAccessEntries(msg, &(parcel->mAccessList) );
01937         }
01938         else if (message_flags & AL_BAN)
01939         {
01940                 parcel->unpackAccessEntries(msg, &(parcel->mBanList) );
01941         }
01942         
01943 
01944 
01945 
01946 
01947         gParcelMgr->notifyObservers();
01948 }
01949 
01950 
01951 
01952 void LLViewerParcelMgr::processParcelDwellReply(LLMessageSystem* msg, void**)
01953 {
01954         LLUUID agent_id;
01955         msg->getUUID("AgentData", "AgentID", agent_id);
01956 
01957         S32 local_id;
01958         msg->getS32("Data", "LocalID", local_id);
01959 
01960         LLUUID parcel_id;
01961         msg->getUUID("Data", "ParcelID", parcel_id);
01962 
01963         F32 dwell;
01964         msg->getF32("Data", "Dwell", dwell);
01965 
01966         if (local_id == gParcelMgr->mCurrentParcel->getLocalID())
01967         {
01968                 gParcelMgr->mSelectedDwell = dwell;
01969                 gParcelMgr->notifyObservers();
01970         }
01971 }
01972 
01973 
01974 void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
01975 {
01976 
01977         LLUUID transactionUUID;
01978         transactionUUID.generate();
01979 
01980         if (!mSelected)
01981         {
01982                 return;
01983         }
01984 
01985         LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth );
01986         if (!region) return;
01987 
01988         LLMessageSystem* msg = gMessageSystem;
01989 
01990         LLParcel* parcel = mCurrentParcel;
01991         if (!parcel) return;
01992 
01993         if (which & AL_ACCESS)
01994         {       
01995                 S32 count = parcel->mAccessList.size();
01996                 S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
01997                 S32 sequence_id = 1;
01998                 BOOL start_message = TRUE;
01999                 BOOL initial = TRUE;
02000 
02001                 access_map_const_iterator cit = parcel->mAccessList.begin();
02002                 access_map_const_iterator end = parcel->mAccessList.end();
02003                 while ( (cit != end) || initial ) 
02004                 {       
02005                         if (start_message) 
02006                         {
02007                                 msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
02008                                 msg->nextBlockFast(_PREHASH_AgentData);
02009                                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
02010                                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
02011                                 msg->nextBlockFast(_PREHASH_Data);
02012                                 msg->addU32Fast(_PREHASH_Flags, AL_ACCESS);
02013                                 msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
02014                                 msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
02015                                 msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
02016                                 msg->addS32Fast(_PREHASH_Sections, num_sections);
02017                                 start_message = FALSE;
02018 
02019                                 if (initial && (cit == end))
02020                                 {
02021                                         
02022                                         msg->nextBlockFast(_PREHASH_List);
02023                                         msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
02024                                         msg->addS32Fast(_PREHASH_Time, 0 );
02025                                         msg->addU32Fast(_PREHASH_Flags, 0 );
02026                                 }
02027 
02028                                 initial = FALSE;
02029                                 sequence_id++;
02030 
02031                         }
02032                         
02033                         while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES)) 
02034                         {
02035 
02036                                 const LLAccessEntry& entry = (*cit).second;
02037                                 
02038                                 msg->nextBlockFast(_PREHASH_List);
02039                                 msg->addUUIDFast(_PREHASH_ID,  entry.mID );
02040                                 msg->addS32Fast(_PREHASH_Time, entry.mTime );
02041                                 msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
02042                                 ++cit;
02043                         }
02044 
02045                         start_message = TRUE;
02046                         msg->sendReliable( region->getHost() );
02047                 }
02048         }
02049 
02050         if (which & AL_BAN)
02051         {       
02052                 S32 count = parcel->mBanList.size();
02053                 S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
02054                 S32 sequence_id = 1;
02055                 BOOL start_message = TRUE;
02056                 BOOL initial = TRUE;
02057 
02058                 access_map_const_iterator cit = parcel->mBanList.begin();
02059                 access_map_const_iterator end = parcel->mBanList.end();
02060                 while ( (cit != end) || initial ) 
02061                 {
02062                         if (start_message) 
02063                         {
02064                                 msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
02065                                 msg->nextBlockFast(_PREHASH_AgentData);
02066                                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
02067                                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
02068                                 msg->nextBlockFast(_PREHASH_Data);
02069                                 msg->addU32Fast(_PREHASH_Flags, AL_BAN);
02070                                 msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
02071                                 msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
02072                                 msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
02073                                 msg->addS32Fast(_PREHASH_Sections, num_sections);
02074                                 start_message = FALSE;
02075 
02076                                 if (initial && (cit == end))
02077                                 {
02078                                         
02079                                         msg->nextBlockFast(_PREHASH_List);
02080                                         msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
02081                                         msg->addS32Fast(_PREHASH_Time, 0 );
02082                                         msg->addU32Fast(_PREHASH_Flags, 0 );
02083                                 }
02084 
02085                                 initial = FALSE;
02086                                 sequence_id++;
02087 
02088                         }
02089                         
02090                         while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES)) 
02091                         {
02092                                 const LLAccessEntry& entry = (*cit).second;
02093                                 
02094                                 msg->nextBlockFast(_PREHASH_List);
02095                                 msg->addUUIDFast(_PREHASH_ID,  entry.mID );
02096                                 msg->addS32Fast(_PREHASH_Time, entry.mTime );
02097                                 msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
02098                                 ++cit;
02099                         }
02100 
02101                         start_message = TRUE;
02102                         msg->sendReliable( region->getHost() );
02103                 }
02104         }
02105 }
02106 
02107 
02108 void LLViewerParcelMgr::deedLandToGroup()
02109 {
02110         char group_name[MAX_STRING];            
02111         gCacheName->getGroupName(mCurrentParcel->getGroupID(), group_name);
02112         LLString::format_map_t args;
02113         args["[AREA]"] = llformat("%d", mCurrentParcel->getArea());
02114         args["[GROUP_NAME]"] = group_name;
02115         if(mCurrentParcel->getContributeWithDeed())
02116         {
02117                 char first_name[DB_FIRST_NAME_BUF_SIZE];                
02118                 first_name[0] = '\0';
02119                 char last_name[DB_FIRST_NAME_BUF_SIZE];         
02120                 last_name[0] = '\0';            
02121                 gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name);
02122                 args["[FIRST_NAME]"] = first_name;
02123                 args["[LAST_NAME]"] = last_name;
02124                 gViewerWindow->alertXml("DeedLandToGroupWithContribution",args, deedAlertCB, NULL);
02125         }
02126         else
02127         {
02128                 gViewerWindow->alertXml("DeedLandToGroup",args, deedAlertCB, NULL);
02129         }
02130 }
02131 
02132 
02133 void LLViewerParcelMgr::deedAlertCB(S32 option, void*)
02134 {
02135         if (option == 0)
02136         {
02137                 LLParcel* parcel = gParcelMgr->getParcelSelection()->getParcel();
02138                 LLUUID group_id;
02139                 if(parcel)
02140                 {
02141                         group_id = parcel->getGroupID();
02142                 }
02143                 gParcelMgr->sendParcelDeed(group_id);
02144         }
02145 }
02146 
02147 
02148 void LLViewerParcelMgr::startReleaseLand()
02149 {
02150         if (!mSelected)
02151         {
02152                 gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
02153                 return;
02154         }
02155 
02156         if (mRequestResult == PARCEL_RESULT_NO_DATA)
02157         {
02158                 gViewerWindow->alertXml("CannotReleaseLandWatingForServer");
02159                 return;
02160         }
02161 
02162         if (mRequestResult == PARCEL_RESULT_MULTIPLE)
02163         {
02164                 gViewerWindow->alertXml("CannotReleaseLandSelected");
02165                 return;
02166         }
02167 
02168         if (!isParcelOwnedByAgent(mCurrentParcel, GP_LAND_RELEASE)
02169                 && !(gAgent.canManageEstate()))
02170         {
02171                 gViewerWindow->alertXml("CannotReleaseLandDontOwn");
02172                 return;
02173         }
02174 
02175         LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
02176         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal(parcel_center);
02177         if (!region)
02178         {
02179                 gViewerWindow->alertXml("CannotReleaseLandRegionNotFound");
02180                 return;
02181         }
02182 
02183 
02184 
02185 
02186 
02187 
02188 
02189 
02190 
02191 
02192 
02193         if (!mCurrentParcelSelection->mWholeParcelSelected)
02194         {
02195                 gViewerWindow->alertXml("CannotReleaseLandPartialSelection");
02196                 return;
02197         }
02198 
02199         
02200         LLStringBase<char>::format_map_t args;
02201         args["[AREA]"] = llformat("%d",mCurrentParcel->getArea());
02202         gViewerWindow->alertXml("ReleaseLandWarning", args,
02203                                 releaseAlertCB, this);
02204 }
02205 
02206 bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
02207 {
02208         if (!parcel)
02209         {
02210                 return false;
02211         }
02212         
02213         if (mSelected  &&  parcel == mCurrentParcel)
02214         {
02215                 if (mRequestResult == PARCEL_RESULT_NO_DATA)
02216                 {
02217                         return false;
02218                 }
02219         }
02220         
02221         const LLUUID& parcelOwner = parcel->getOwnerID();
02222         const LLUUID& authorizeBuyer = parcel->getAuthorizedBuyerID();
02223 
02224         if (parcel->isPublic())
02225         {
02226                 return true;    
02227         }
02228         
02229         bool isForSale = parcel->getForSale()
02230                         && ((parcel->getSalePrice() > 0) || (authorizeBuyer.notNull()));
02231                         
02232         bool isEmpowered
02233                 = forGroup ? gAgent.hasPowerInActiveGroup(GP_LAND_DEED) == TRUE : true;
02234                 
02235         bool isOwner
02236                 = parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID());
02237         
02238         bool isAuthorized
02239                 = (authorizeBuyer.isNull() || (gAgent.getID() == authorizeBuyer));
02240         
02241         return isForSale && !isOwner && isAuthorized  && isEmpowered;
02242 }
02243 
02244 
02245 void LLViewerParcelMgr::startBuyLand(BOOL is_for_group)
02246 {
02247         LLFloaterBuyLand::buyLand(getSelectionRegion(), mCurrentParcelSelection, is_for_group == TRUE);
02248 }
02249 
02250 void LLViewerParcelMgr::startSellLand()
02251 {
02252         LLFloaterSellLand::sellLand(getSelectionRegion(), mCurrentParcelSelection);
02253 }
02254 
02255 void LLViewerParcelMgr::startDivideLand()
02256 {
02257         if (!mSelected)
02258         {
02259                 gViewerWindow->alertXml("CannotDivideLandNothingSelected");
02260                 return;
02261         }
02262 
02263         if (mCurrentParcelSelection->mWholeParcelSelected)
02264         {
02265                 gViewerWindow->alertXml("CannotDivideLandPartialSelection");
02266                 return;
02267         }
02268 
02269         gViewerWindow->alertXml("LandDivideWarning", 
02270                 callbackDivideLand,
02271                 this);
02272 }
02273 
02274 
02275 void LLViewerParcelMgr::callbackDivideLand(S32 option, void* data)
02276 {
02277         LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
02278 
02279         LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
02280         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal(parcel_center);
02281         if (!region)
02282         {
02283                 gViewerWindow->alertXml("CannotDivideLandNoRegion");
02284                 return;
02285         }
02286 
02287         if (0 == option)
02288         {
02289                 LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
02290                 LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
02291 
02292                 LLMessageSystem* msg = gMessageSystem;
02293                 msg->newMessage("ParcelDivide");
02294                 msg->nextBlock("AgentData");
02295                 msg->addUUID("AgentID", gAgent.getID());
02296                 msg->addUUID("SessionID", gAgent.getSessionID());
02297                 msg->nextBlock("ParcelData");
02298                 msg->addF32("West", west_south.mV[VX]);
02299                 msg->addF32("South", west_south.mV[VY]);
02300                 msg->addF32("East", east_north.mV[VX]);
02301                 msg->addF32("North", east_north.mV[VY]);
02302                 msg->sendReliable(region->getHost());
02303         }
02304 }
02305 
02306 
02307 void LLViewerParcelMgr::startJoinLand()
02308 {
02309         if (!mSelected)
02310         {
02311                 gViewerWindow->alertXml("CannotJoinLandNothingSelected");
02312                 return;
02313         }
02314 
02315         if (mCurrentParcelSelection->mWholeParcelSelected)
02316         {
02317                 gViewerWindow->alertXml("CannotJoinLandEntireParcelSelected");
02318                 return;
02319         }
02320 
02321         if (!mCurrentParcelSelection->mSelectedMultipleOwners)
02322         {
02323                 gViewerWindow->alertXml("CannotJoinLandSelection");
02324                 return;
02325         }
02326 
02327         gViewerWindow->alertXml("JoinLandWarning",
02328                 callbackJoinLand,
02329                 this);
02330 }
02331 
02332 
02333 void LLViewerParcelMgr::callbackJoinLand(S32 option, void* data)
02334 {
02335         LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
02336 
02337         LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
02338         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal(parcel_center);
02339         if (!region)
02340         {
02341                 gViewerWindow->alertXml("CannotJoinLandNoRegion");
02342                 return;
02343         }
02344 
02345         if (0 == option)
02346         {
02347                 LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
02348                 LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
02349 
02350                 LLMessageSystem* msg = gMessageSystem;
02351                 msg->newMessage("ParcelJoin");
02352                 msg->nextBlock("AgentData");
02353                 msg->addUUID("AgentID", gAgent.getID());
02354                 msg->addUUID("SessionID", gAgent.getSessionID());
02355                 msg->nextBlock("ParcelData");
02356                 msg->addF32("West", west_south.mV[VX]);
02357                 msg->addF32("South", west_south.mV[VY]);
02358                 msg->addF32("East", east_north.mV[VX]);
02359                 msg->addF32("North", east_north.mV[VY]);
02360                 msg->sendReliable(region->getHost());
02361         }
02362 }
02363 
02364 
02365 void LLViewerParcelMgr::startDeedLandToGroup()
02366 {
02367         if (!mSelected || !mCurrentParcel)
02368         {
02369                 gViewerWindow->alertXml("CannotDeedLandNothingSelected");
02370                 return;
02371         }
02372 
02373         if (mRequestResult == PARCEL_RESULT_NO_DATA)
02374         {
02375                 gViewerWindow->alertXml("CannotDeedLandWaitingForServer");
02376                 return;
02377         }
02378 
02379         if (mRequestResult == PARCEL_RESULT_MULTIPLE)
02380         {
02381                 gViewerWindow->alertXml("CannotDeedLandMultipleSelected");
02382                 return;
02383         }
02384 
02385         LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
02386         LLViewerRegion* region = gWorldp->getRegionFromPosGlobal(parcel_center);
02387         if (!region)
02388         {
02389                 gViewerWindow->alertXml("CannotDeedLandNoRegion");
02390                 return;
02391         }
02392 
02393         
02394 
02395 
02396 
02397 
02398 
02399 
02400 
02401 
02402 
02403 
02404 
02405 
02406 
02407         deedLandToGroup();
02408 }
02409 void LLViewerParcelMgr::reclaimParcel()
02410 {
02411         LLParcel* parcel = gParcelMgr->getParcelSelection()->getParcel();
02412         LLViewerRegion* regionp = gParcelMgr->getSelectionRegion();
02413         if(parcel && parcel->getOwnerID().notNull()
02414            && (parcel->getOwnerID() != gAgent.getID())
02415            && regionp && (regionp->getOwner() == gAgent.getID()))
02416         {
02417                 LLMessageSystem* msg = gMessageSystem;
02418                 msg->newMessage("ParcelReclaim");
02419                 msg->nextBlock("AgentData");
02420                 msg->addUUID("AgentID", gAgent.getID());
02421                 msg->addUUID("SessionID", gAgent.getSessionID());
02422                 msg->nextBlock("Data");
02423                 msg->addS32("LocalID", parcel->getLocalID());
02424                 msg->sendReliable(regionp->getHost());
02425         }
02426 }
02427 
02428 
02429 void LLViewerParcelMgr::releaseAlertCB(S32 option, void *)
02430 {
02431         if (option == 0)
02432         {
02433                 
02434                 gParcelMgr->sendParcelRelease();
02435         }
02436 }
02437 
02438 void LLViewerParcelMgr::buyPass()
02439 {
02440         LLParcel* parcel = getParcelSelection()->getParcel();
02441         if (!parcel) return;
02442 
02443         LLViewerRegion* region = getSelectionRegion();
02444         if (!region) return;
02445 
02446         LLMessageSystem* msg = gMessageSystem;
02447         msg->newMessageFast(_PREHASH_ParcelBuyPass);
02448         msg->nextBlock("AgentData");
02449         msg->addUUID("AgentID", gAgent.getID());
02450         msg->addUUID("SessionID", gAgent.getSessionID());
02451         msg->nextBlockFast(_PREHASH_ParcelData);
02452         msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
02453         msg->sendReliable( region->getHost() );
02454 }
02455 
02456 
02457 BOOL LLViewerParcelMgr::isCollisionBanned()     
02458 { 
02459         if ((mCollisionBanned == BA_ALLOWED) || (mCollisionBanned == BA_NOT_ON_LIST) || (mCollisionBanned == BA_NOT_IN_GROUP))
02460                 return FALSE;
02461         else 
02462                 return TRUE;
02463 }
02464 
02465 
02466 
02467 BOOL LLViewerParcelMgr::isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power)
02468 {
02469         if (!parcelp)
02470         {
02471                 return FALSE;
02472         }
02473 
02474         
02475         if (gAgent.isGodlike())
02476         {
02477                 return TRUE;
02478         }
02479 
02480         
02481         if (parcelp->getOwnerID() == gAgent.getID())
02482         {
02483                 return TRUE;
02484         }
02485 
02486         
02487         if (parcelp->isPublic())
02488         {
02489                 return FALSE;
02490         }
02491 
02492         
02493         
02494         return gAgent.hasPowerInGroup(parcelp->getOwnerID(), group_proxy_power);
02495 }
02496 
02497 
02498 
02499 BOOL LLViewerParcelMgr::isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power)
02500 {
02501         
02502         BOOL rv = FALSE;
02503         if (parcelp)
02504         {
02505                 
02506                 
02507                 rv = isParcelOwnedByAgent(parcelp, group_proxy_power);
02508 
02509                 
02510                 if( (gAgent.getID() == parcelp->getOwnerID())
02511                         && !gAgent.isGodlike()
02512                         && (parcelp->getOwnershipStatus() != LLParcel::OS_LEASED) )
02513                 {
02514                         rv = FALSE;
02515                 }
02516         }
02517         return rv;
02518 }
02519 
02520 void sanitize_corners(const LLVector3d &corner1,
02521                                                                                 const LLVector3d &corner2,
02522                                                                                 LLVector3d &west_south_bottom,
02523                                                                                 LLVector3d &east_north_top)
02524 {
02525         west_south_bottom.mdV[VX] = llmin( corner1.mdV[VX], corner2.mdV[VX] );
02526         west_south_bottom.mdV[VY] = llmin( corner1.mdV[VY], corner2.mdV[VY] );
02527         west_south_bottom.mdV[VZ] = llmin( corner1.mdV[VZ], corner2.mdV[VZ] );
02528 
02529         east_north_top.mdV[VX] = llmax( corner1.mdV[VX], corner2.mdV[VX] );
02530         east_north_top.mdV[VY] = llmax( corner1.mdV[VY], corner2.mdV[VY] );
02531         east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] );
02532 }
02533 
02534 
02535 
02536 
02537 LLParcelSelection::LLParcelSelection() : 
02538         mParcel(NULL),
02539         mSelectedMultipleOwners(FALSE),
02540         mWholeParcelSelected(FALSE),
02541         mSelectedSelfCount(0),
02542         mSelectedOtherCount(0),
02543         mSelectedPublicCount(0)
02544 {
02545 }
02546 
02547 LLParcelSelection::LLParcelSelection(LLParcel* parcel)  : 
02548         mParcel(parcel),
02549         mSelectedMultipleOwners(FALSE),
02550         mWholeParcelSelected(FALSE),
02551         mSelectedSelfCount(0),
02552         mSelectedOtherCount(0),
02553         mSelectedPublicCount(0)
02554 {
02555 }
02556 
02557 LLParcelSelection::~LLParcelSelection()
02558 {
02559 }
02560 
02561 BOOL LLParcelSelection::getMultipleOwners() const
02562 {
02563         return mSelectedMultipleOwners;
02564 }
02565 
02566 
02567 BOOL LLParcelSelection::getWholeParcelSelected() const
02568 {
02569         return mWholeParcelSelected;
02570 }
02571 
02572 
02573 S32 LLParcelSelection::getClaimableArea() const
02574 {
02575         const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS );
02576         return mSelectedPublicCount * UNIT_AREA;
02577 }
02578 
02579 bool LLParcelSelection::hasOthersSelected() const
02580 {
02581         return mSelectedOtherCount != 0;
02582 }
02583 
02584 static LLPointer<LLParcelSelection> sNullSelection;
02585 
02586 LLParcelSelection* get_null_parcel_selection()
02587 {
02588         if (sNullSelection.isNull())
02589         {
02590                 sNullSelection = new LLParcelSelection;
02591         }
02592         
02593         return sNullSelection;
02594 }
02595 
02596 void LLViewerParcelMgr::cleanupGlobals()
02597 {
02598         delete gParcelMgr;
02599         gParcelMgr = NULL;
02600         sNullSelection = NULL;
02601 }