llviewerparcelmgr.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:72k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerparcelmgr.cpp
  3.  * @brief Viewer-side representation of owned land
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerparcelmgr.h"
  34. // Library includes
  35. #include "llaudioengine.h"
  36. #include "indra_constants.h"
  37. #include "llcachename.h"
  38. #include "llgl.h"
  39. #include "llnotifications.h"
  40. #include "llnotificationsutil.h"
  41. #include "llparcel.h"
  42. #include "llsecondlifeurls.h"
  43. #include "message.h"
  44. #include "llfloaterreg.h"
  45. // Viewer includes
  46. #include "llagent.h"
  47. #include "llviewerwindow.h"
  48. #include "llviewercontrol.h"
  49. //#include "llfirstuse.h"
  50. #include "llfloaterbuyland.h"
  51. #include "llfloatergroups.h"
  52. #include "llpanelnearbymedia.h"
  53. #include "llfloatersellland.h"
  54. #include "llfloatertools.h"
  55. #include "llparcelselection.h"
  56. #include "llresmgr.h"
  57. #include "llsdutil.h"
  58. #include "llsdutil_math.h"
  59. #include "llstatusbar.h"
  60. #include "llui.h"
  61. #include "llviewertexture.h"
  62. #include "llviewertexturelist.h"
  63. #include "llviewermenu.h"
  64. #include "llviewerparcelmedia.h"
  65. #include "llviewerparceloverlay.h"
  66. #include "llviewerregion.h"
  67. #include "llworld.h"
  68. #include "roles_constants.h"
  69. #include "llweb.h"
  70. const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
  71. // Globals
  72. U8* LLViewerParcelMgr::sPackedOverlay = NULL;
  73. LLUUID gCurrentMovieID = LLUUID::null;
  74. LLPointer<LLViewerTexture> sBlockedImage;
  75. LLPointer<LLViewerTexture> sPassImage;
  76. // Local functions
  77. void optionally_start_music(const std::string& music_url);
  78. void callback_start_music(S32 option, void* data);
  79. void optionally_prepare_video(const LLParcel *parcelp);
  80. void callback_prepare_video(S32 option, void* data);
  81. void prepare_video(const LLParcel *parcelp);
  82. void start_video(const LLParcel *parcelp);
  83. void stop_video();
  84. bool callback_god_force_owner(const LLSD&, const LLSD&);
  85. struct LLGodForceOwnerData
  86. {
  87. LLUUID mOwnerID;
  88. S32 mLocalID;
  89. LLHost mHost;
  90. LLGodForceOwnerData(
  91. const LLUUID& owner_id,
  92. S32 local_parcel_id,
  93. const LLHost& host) :
  94. mOwnerID(owner_id),
  95. mLocalID(local_parcel_id),
  96. mHost(host) {}
  97. };
  98. //
  99. // Methods
  100. //
  101. LLViewerParcelMgr::LLViewerParcelMgr()
  102. : mSelected(FALSE),
  103. mRequestResult(0),
  104. mWestSouth(),
  105. mEastNorth(),
  106. mSelectedDwell(0.f),
  107. mAgentParcelSequenceID(-1),
  108. mHoverRequestResult(0),
  109. mHoverWestSouth(),
  110. mHoverEastNorth(),
  111. mRenderCollision(FALSE),
  112. mRenderSelection(TRUE),
  113. mCollisionBanned(0),
  114. mCollisionTimer(),
  115. mMediaParcelId(0),
  116. mMediaRegionId(0)
  117. {
  118. mCurrentParcel = new LLParcel();
  119. mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
  120. mFloatingParcelSelection = new LLParcelSelection(mCurrentParcel);
  121. mAgentParcel = new LLParcel();
  122. mHoverParcel = new LLParcel();
  123. mCollisionParcel = new LLParcel();
  124. mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
  125. mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
  126. resetSegments(mHighlightSegments);
  127. mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
  128. resetSegments(mCollisionSegments);
  129. // JC: Resolved a merge conflict here, eliminated
  130. // mBlockedImage->setAddressMode(LLTexUnit::TAM_WRAP);
  131. // because it is done in llviewertexturelist.cpp
  132. mBlockedImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png");
  133. mPassImage = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png");
  134. S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;
  135. sPackedOverlay = new U8[overlay_size];
  136. mAgentParcelOverlay = new U8[mParcelsPerEdge * mParcelsPerEdge];
  137. S32 i;
  138. for (i = 0; i < mParcelsPerEdge * mParcelsPerEdge; i++)
  139. {
  140. mAgentParcelOverlay[i] = 0;
  141. }
  142. mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport
  143. }
  144. LLViewerParcelMgr::~LLViewerParcelMgr()
  145. {
  146. mCurrentParcelSelection->setParcel(NULL);
  147. mCurrentParcelSelection = NULL;
  148. mFloatingParcelSelection->setParcel(NULL);
  149. mFloatingParcelSelection = NULL;
  150. delete mCurrentParcel;
  151. mCurrentParcel = NULL;
  152. delete mAgentParcel;
  153. mAgentParcel = NULL;
  154. delete mCollisionParcel;
  155. mCollisionParcel = NULL;
  156. delete mHoverParcel;
  157. mHoverParcel = NULL;
  158. delete[] mHighlightSegments;
  159. mHighlightSegments = NULL;
  160. delete[] mCollisionSegments;
  161. mCollisionSegments = NULL;
  162. delete[] sPackedOverlay;
  163. sPackedOverlay = NULL;
  164. delete[] mAgentParcelOverlay;
  165. mAgentParcelOverlay = NULL;
  166. sBlockedImage = NULL;
  167. sPassImage = NULL;
  168. }
  169. void LLViewerParcelMgr::dump()
  170. {
  171. llinfos << "Parcel Manager Dump" << llendl;
  172. llinfos << "mSelected " << S32(mSelected) << llendl;
  173. llinfos << "Selected parcel: " << llendl;
  174. llinfos << mWestSouth << " to " << mEastNorth << llendl;
  175. mCurrentParcel->dump();
  176. llinfos << "banning " << mCurrentParcel->mBanList.size() << llendl;
  177. access_map_const_iterator cit = mCurrentParcel->mBanList.begin();
  178. access_map_const_iterator end = mCurrentParcel->mBanList.end();
  179. for ( ; cit != end; ++cit)
  180. {
  181. llinfos << "ban id " << (*cit).first << llendl;
  182. }
  183. llinfos << "Hover parcel:" << llendl;
  184. mHoverParcel->dump();
  185. llinfos << "Agent parcel:" << llendl;
  186. mAgentParcel->dump();
  187. }
  188. LLViewerRegion* LLViewerParcelMgr::getSelectionRegion()
  189. {
  190. return LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  191. }
  192. void LLViewerParcelMgr::getDisplayInfo(S32* area_out, S32* claim_out,
  193.    S32* rent_out,
  194.    BOOL* for_sale_out,
  195.    F32* dwell_out)
  196. {
  197. S32 area = 0;
  198. S32 price = 0;
  199. S32 rent = 0;
  200. BOOL for_sale = FALSE;
  201. F32 dwell = 0.f;
  202. if (mSelected)
  203. {
  204. if (mCurrentParcelSelection->mSelectedMultipleOwners)
  205. {
  206. area = mCurrentParcelSelection->getClaimableArea();
  207. }
  208. else
  209. {
  210. area = getSelectedArea();
  211. }
  212. if (mCurrentParcel->getForSale())
  213. {
  214. price = mCurrentParcel->getSalePrice();
  215. for_sale = TRUE;
  216. }
  217. else
  218. {
  219. price = area * mCurrentParcel->getClaimPricePerMeter();
  220. for_sale = FALSE;
  221. }
  222. rent = mCurrentParcel->getTotalRent();
  223. dwell = mSelectedDwell;
  224. }
  225. *area_out = area;
  226. *claim_out = price;
  227. *rent_out = rent;
  228. *for_sale_out = for_sale;
  229. *dwell_out = dwell;
  230. }
  231. S32 LLViewerParcelMgr::getSelectedArea() const
  232. {
  233. S32 rv = 0;
  234. if(mSelected && mCurrentParcel && mCurrentParcelSelection->mWholeParcelSelected)
  235. {
  236. rv = mCurrentParcel->getArea();
  237. }
  238. else if(mSelected)
  239. {
  240. F64 width = mEastNorth.mdV[VX] - mWestSouth.mdV[VX];
  241. F64 height = mEastNorth.mdV[VY] - mWestSouth.mdV[VY];
  242. F32 area = (F32)(width * height);
  243. rv = llround(area);
  244. }
  245. return rv;
  246. }
  247. void LLViewerParcelMgr::resetSegments(U8* segments)
  248. {
  249. S32 i;
  250. S32 count = (mParcelsPerEdge+1)*(mParcelsPerEdge+1);
  251. for (i = 0; i < count; i++)
  252. {
  253. segments[i] = 0x0;
  254. }
  255. }
  256. void LLViewerParcelMgr::writeHighlightSegments(F32 west, F32 south, F32 east,
  257.    F32 north)
  258. {
  259. S32 x, y;
  260. S32 min_x = llround( west / PARCEL_GRID_STEP_METERS );
  261. S32 max_x = llround( east / PARCEL_GRID_STEP_METERS );
  262. S32 min_y = llround( south / PARCEL_GRID_STEP_METERS );
  263. S32 max_y = llround( north / PARCEL_GRID_STEP_METERS );
  264. const S32 STRIDE = mParcelsPerEdge+1;
  265. // south edge
  266. y = min_y;
  267. for (x = min_x; x < max_x; x++)
  268. {
  269. // exclusive OR means that writing to this segment twice
  270. // will turn it off
  271. mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
  272. }
  273. // west edge
  274. x = min_x;
  275. for (y = min_y; y < max_y; y++)
  276. {
  277. mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
  278. }
  279. // north edge - draw the south border on the y+1'th cell,
  280. // which given C-style arrays, is item foo[max_y]
  281. y = max_y;
  282. for (x = min_x; x < max_x; x++)
  283. {
  284. mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
  285. }
  286. // east edge - draw west border on x+1'th cell
  287. x = max_x;
  288. for (y = min_y; y < max_y; y++)
  289. {
  290. mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
  291. }
  292. }
  293. void LLViewerParcelMgr::writeSegmentsFromBitmap(U8* bitmap, U8* segments)
  294. {
  295. S32 x;
  296. S32 y;
  297. const S32 IN_STRIDE = mParcelsPerEdge;
  298. const S32 OUT_STRIDE = mParcelsPerEdge+1;
  299. for (y = 0; y < IN_STRIDE; y++)
  300. {
  301. x = 0;
  302. while( x < IN_STRIDE )
  303. {
  304. U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
  305. S32 bit;
  306. for (bit = 0; bit < 8; bit++)
  307. {
  308. if (byte & (1 << bit) )
  309. {
  310. S32 out = x+y*OUT_STRIDE;
  311. // This and one above it
  312. segments[out]            ^= SOUTH_MASK;
  313. segments[out+OUT_STRIDE] ^= SOUTH_MASK;
  314. // This and one to the right
  315. segments[out]   ^= WEST_MASK;
  316. segments[out+1] ^= WEST_MASK;
  317. }
  318. x++;
  319. }
  320. }
  321. }
  322. }
  323. void LLViewerParcelMgr::writeAgentParcelFromBitmap(U8* bitmap)
  324. {
  325. S32 x;
  326. S32 y;
  327. const S32 IN_STRIDE = mParcelsPerEdge;
  328. for (y = 0; y < IN_STRIDE; y++)
  329. {
  330. x = 0;
  331. while( x < IN_STRIDE )
  332. {
  333. U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
  334. S32 bit;
  335. for (bit = 0; bit < 8; bit++)
  336. {
  337. if (byte & (1 << bit) )
  338. {
  339. mAgentParcelOverlay[x+y*IN_STRIDE] = 1;
  340. }
  341. else
  342. {
  343. mAgentParcelOverlay[x+y*IN_STRIDE] = 0;
  344. }
  345. x++;
  346. }
  347. }
  348. }
  349. }
  350. // Given a point, find the PARCEL_GRID_STEP x PARCEL_GRID_STEP block
  351. // containing it and select that.
  352. LLParcelSelectionHandle LLViewerParcelMgr::selectParcelAt(const LLVector3d& pos_global)
  353. {
  354. LLVector3d southwest = pos_global;
  355. LLVector3d northeast = pos_global;
  356. southwest -= LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
  357. southwest.mdV[VX] = llround( southwest.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
  358. southwest.mdV[VY] = llround( southwest.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
  359. northeast += LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
  360. northeast.mdV[VX] = llround( northeast.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
  361. northeast.mdV[VY] = llround( northeast.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
  362. // Snap to parcel
  363. return selectLand( southwest, northeast, TRUE );
  364. }
  365. // Tries to select the parcel inside the rectangle
  366. LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle()
  367. {
  368. return selectLand(mWestSouth, mEastNorth, TRUE);
  369. }
  370. void LLViewerParcelMgr::selectCollisionParcel()
  371. {
  372. // BUG: Claim to be in the agent's region
  373. mWestSouth = gAgent.getRegion()->getOriginGlobal();
  374. mEastNorth = mWestSouth;
  375. mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0);
  376. // BUG: must be in the sim you are in
  377. LLMessageSystem *msg = gMessageSystem;
  378. msg->newMessageFast(_PREHASH_ParcelPropertiesRequestByID);
  379. msg->nextBlockFast(_PREHASH_AgentID);
  380. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  381. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  382. msg->nextBlockFast(_PREHASH_ParcelData);
  383. msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
  384. msg->addS32Fast(_PREHASH_LocalID, mCollisionParcel->getLocalID() );
  385. gAgent.sendReliableMessage();
  386. mRequestResult = PARCEL_RESULT_NO_DATA;
  387. // Hack: Copy some data over temporarily
  388. mCurrentParcel->setName( mCollisionParcel->getName() );
  389. mCurrentParcel->setDesc( mCollisionParcel->getDesc() );
  390. mCurrentParcel->setPassPrice(mCollisionParcel->getPassPrice());
  391. mCurrentParcel->setPassHours(mCollisionParcel->getPassHours());
  392. // clear the list of segments to prevent flashing
  393. resetSegments(mHighlightSegments);
  394. mFloatingParcelSelection->setParcel(mCurrentParcel);
  395. mCurrentParcelSelection->setParcel(NULL);
  396. mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
  397. mSelected = TRUE;
  398. mCurrentParcelSelection->mWholeParcelSelected = TRUE;
  399. notifyObservers();
  400. return;
  401. }
  402. // snap_selection = auto-select the hit parcel, if there is exactly one
  403. LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1, const LLVector3d &corner2,
  404.    BOOL snap_selection)
  405. {
  406. sanitize_corners( corner1, corner2, mWestSouth, mEastNorth );
  407. // ...x isn't more than one meter away
  408. F32 delta_x = getSelectionWidth();
  409. if (delta_x * delta_x <= 1.f * 1.f)
  410. {
  411. mSelected = FALSE;
  412. notifyObservers();
  413. return NULL;
  414. }
  415. // ...y isn't more than one meter away
  416. F32 delta_y = getSelectionHeight();
  417. if (delta_y * delta_y <= 1.f * 1.f)
  418. {
  419. mSelected = FALSE;
  420. notifyObservers();
  421. return NULL;
  422. }
  423. // Can't select across region boundary
  424. // We need to pull in the upper right corner by a little bit to allow
  425. // selection up to the x = 256 or y = 256 edge.
  426. LLVector3d east_north_region_check( mEastNorth );
  427. east_north_region_check.mdV[VX] -= 0.5;
  428. east_north_region_check.mdV[VY] -= 0.5;
  429. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth);
  430. LLViewerRegion *region_other = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
  431. if(!region)
  432. {
  433. // just in case they somehow selected no land.
  434. mSelected = FALSE;
  435. return NULL;
  436. }
  437. if (region != region_other)
  438. {
  439. LLNotificationsUtil::add("CantSelectLandFromMultipleRegions");
  440. mSelected = FALSE;
  441. notifyObservers();
  442. return NULL;
  443. }
  444. // Build region global copies of corners
  445. LLVector3 wsb_region = region->getPosRegionFromGlobal( mWestSouth );
  446. LLVector3 ent_region = region->getPosRegionFromGlobal( mEastNorth );
  447. // Send request message
  448. LLMessageSystem *msg = gMessageSystem;
  449. msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
  450. msg->nextBlockFast(_PREHASH_AgentData);
  451. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  452. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  453. msg->nextBlockFast(_PREHASH_ParcelData);
  454. msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
  455. msg->addF32Fast(_PREHASH_West,  wsb_region.mV[VX] );
  456. msg->addF32Fast(_PREHASH_South, wsb_region.mV[VY] );
  457. msg->addF32Fast(_PREHASH_East,  ent_region.mV[VX] );
  458. msg->addF32Fast(_PREHASH_North, ent_region.mV[VY] );
  459. msg->addBOOL("SnapSelection", snap_selection);
  460. msg->sendReliable( region->getHost() );
  461. mRequestResult = PARCEL_RESULT_NO_DATA;
  462. // clear the list of segments to prevent flashing
  463. resetSegments(mHighlightSegments);
  464. mFloatingParcelSelection->setParcel(mCurrentParcel);
  465. mCurrentParcelSelection->setParcel(NULL);
  466. mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
  467. mSelected = TRUE;
  468. mCurrentParcelSelection->mWholeParcelSelected = snap_selection;
  469. notifyObservers();
  470. return mCurrentParcelSelection;
  471. }
  472. void LLViewerParcelMgr::deselectUnused()
  473. {
  474. // no more outstanding references to this selection, other than our own
  475. if (mCurrentParcelSelection->getNumRefs() == 1 && mFloatingParcelSelection->getNumRefs() == 1)
  476. {
  477. deselectLand();
  478. }
  479. }
  480. void LLViewerParcelMgr::deselectLand()
  481. {
  482. if (mSelected)
  483. {
  484. mSelected = FALSE;
  485. // Invalidate the selected parcel
  486. mCurrentParcel->setLocalID(-1);
  487. mCurrentParcel->mAccessList.clear();
  488. mCurrentParcel->mBanList.clear();
  489. //mCurrentParcel->mRenterList.reset();
  490. mSelectedDwell = 0.f;
  491. // invalidate parcel selection so that existing users of this selection can clean up
  492. mCurrentParcelSelection->setParcel(NULL);
  493. mFloatingParcelSelection->setParcel(NULL);
  494. // create new parcel selection
  495. mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
  496. notifyObservers(); // Notify observers *after* changing the parcel selection
  497. }
  498. }
  499. void LLViewerParcelMgr::addObserver(LLParcelObserver* observer)
  500. {
  501. mObservers.put(observer);
  502. }
  503. void LLViewerParcelMgr::removeObserver(LLParcelObserver* observer)
  504. {
  505. mObservers.removeObj(observer);
  506. }
  507. // Call this method when it's time to update everyone on a new state.
  508. // Copy the list because an observer could respond by removing itself
  509. // from the list.
  510. void LLViewerParcelMgr::notifyObservers()
  511. {
  512. LLDynamicArray<LLParcelObserver*> observers;
  513. S32 count = mObservers.count();
  514. S32 i;
  515. for(i = 0; i < count; ++i)
  516. {
  517. observers.put(mObservers.get(i));
  518. }
  519. for(i = 0; i < count; ++i)
  520. {
  521. observers.get(i)->changed();
  522. }
  523. }
  524. //
  525. // ACCESSORS
  526. //
  527. BOOL LLViewerParcelMgr::selectionEmpty() const
  528. {
  529. return !mSelected;
  530. }
  531. LLParcelSelectionHandle LLViewerParcelMgr::getParcelSelection() const
  532. {
  533. return mCurrentParcelSelection;
  534. }
  535. LLParcelSelectionHandle LLViewerParcelMgr::getFloatingParcelSelection() const
  536. {
  537. return mFloatingParcelSelection;
  538. }
  539. LLParcel *LLViewerParcelMgr::getAgentParcel() const
  540. {
  541. return mAgentParcel;
  542. }
  543. // Return whether the agent can build on the land they are on
  544. bool LLViewerParcelMgr::allowAgentBuild() const
  545. {
  546. if (mAgentParcel)
  547. {
  548. return (gAgent.isGodlike() ||
  549. (mAgentParcel->allowModifyBy(gAgent.getID(), gAgent.getGroupID())) ||
  550. (isParcelOwnedByAgent(mAgentParcel, GP_LAND_ALLOW_CREATE)));
  551. }
  552. else
  553. {
  554. return gAgent.isGodlike();
  555. }
  556. }
  557. // Return whether anyone can build on the given parcel
  558. bool LLViewerParcelMgr::allowAgentBuild(const LLParcel* parcel) const
  559. {
  560. return parcel->getAllowModify();
  561. }
  562. bool LLViewerParcelMgr::allowAgentVoice() const
  563. {
  564. return allowAgentVoice(gAgent.getRegion(), mAgentParcel);
  565. }
  566. bool LLViewerParcelMgr::allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const
  567. {
  568. return region && region->isVoiceEnabled()
  569. && parcel && parcel->getParcelFlagAllowVoice();
  570. }
  571. bool LLViewerParcelMgr::allowAgentFly(const LLViewerRegion* region, const LLParcel* parcel) const
  572. {
  573. return region && !region->getBlockFly()
  574. && parcel && parcel->getAllowFly();
  575. }
  576. // Can the agent be pushed around by LLPushObject?
  577. bool LLViewerParcelMgr::allowAgentPush(const LLViewerRegion* region, const LLParcel* parcel) const
  578. {
  579. return region && !region->getRestrictPushObject()
  580. && parcel && !parcel->getRestrictPushObject();
  581. }
  582. bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LLParcel* parcel) const
  583. {
  584. // *NOTE: This code does not take into account group-owned parcels
  585. // and the flag to allow group-owned scripted objects to run.
  586. // This mirrors the traditional menu bar parcel icon code, but is not
  587. // technically correct.
  588. return region
  589. && !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
  590. && !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
  591. && parcel
  592. && parcel->getAllowOtherScripts();
  593. }
  594. bool LLViewerParcelMgr::allowAgentDamage(const LLViewerRegion* region, const LLParcel* parcel) const
  595. {
  596. return (region && region->getAllowDamage())
  597. || (parcel && parcel->getAllowDamage());
  598. }
  599. BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const
  600. {
  601. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
  602. if (!region) return FALSE;
  603. LLViewerParcelOverlay* overlay = region->getParcelOverlay();
  604. if (!overlay) return FALSE;
  605. LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
  606. return overlay->isOwned( pos_region );
  607. }
  608. BOOL LLViewerParcelMgr::isOwnedSelfAt(const LLVector3d& pos_global) const
  609. {
  610. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
  611. if (!region) return FALSE;
  612. LLViewerParcelOverlay* overlay = region->getParcelOverlay();
  613. if (!overlay) return FALSE;
  614. LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
  615. return overlay->isOwnedSelf( pos_region );
  616. }
  617. BOOL LLViewerParcelMgr::isOwnedOtherAt(const LLVector3d& pos_global) const
  618. {
  619. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
  620. if (!region) return FALSE;
  621. LLViewerParcelOverlay* overlay = region->getParcelOverlay();
  622. if (!overlay) return FALSE;
  623. LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
  624. return overlay->isOwnedOther( pos_region );
  625. }
  626. BOOL LLViewerParcelMgr::isSoundLocal(const LLVector3d& pos_global) const
  627. {
  628. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
  629. if (!region) return FALSE;
  630. LLViewerParcelOverlay* overlay = region->getParcelOverlay();
  631. if (!overlay) return FALSE;
  632. LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
  633. return overlay->isSoundLocal( pos_region );
  634. }
  635. BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const
  636. {
  637. BOOL in_agent_parcel = inAgentParcel(pos_global);
  638. if (in_agent_parcel)
  639. {
  640. // In same parcel as the agent
  641. return TRUE;
  642. }
  643. else
  644. {
  645. if (LLViewerParcelMgr::getInstance()->getAgentParcel()->getSoundLocal())
  646. {
  647. // Not in same parcel, and agent parcel only has local sound
  648. return FALSE;
  649. }
  650. else if (LLViewerParcelMgr::getInstance()->isSoundLocal(pos_global))
  651. {
  652. // Not in same parcel, and target parcel only has local sound
  653. return FALSE;
  654. }
  655. else
  656. {
  657. // Not in same parcel, but neither are local sound
  658. return TRUE;
  659. }
  660. }
  661. }
  662. BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const
  663. {
  664. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global);
  665. LLViewerRegion* agent_region = gAgent.getRegion();
  666. if (!region || !agent_region)
  667. return FALSE;
  668. if (region != agent_region)
  669. {
  670. // Can't be in the agent parcel if you're not in the same region.
  671. return FALSE;
  672. }
  673. LLVector3 pos_region = agent_region->getPosRegionFromGlobal(pos_global);
  674. S32 row =    S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);
  675. S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS);
  676. if (mAgentParcelOverlay[row*mParcelsPerEdge + column])
  677. {
  678. return TRUE;
  679. }
  680. else
  681. {
  682. return FALSE;
  683. }
  684. }
  685. // Returns NULL when there is no valid data.
  686. LLParcel* LLViewerParcelMgr::getHoverParcel() const
  687. {
  688. if (mHoverRequestResult == PARCEL_RESULT_SUCCESS)
  689. {
  690. return mHoverParcel;
  691. }
  692. else
  693. {
  694. return NULL;
  695. }
  696. }
  697. // Returns NULL when there is no valid data.
  698. LLParcel* LLViewerParcelMgr::getCollisionParcel() const
  699. {
  700. if (mRenderCollision)
  701. {
  702. return mCollisionParcel;
  703. }
  704. else
  705. {
  706. return NULL;
  707. }
  708. }
  709. //
  710. // UTILITIES
  711. //
  712. void LLViewerParcelMgr::render()
  713. {
  714. if (mSelected && mRenderSelection)
  715. {
  716. // Rendering is done in agent-coordinates, so need to supply
  717. // an appropriate offset to the render code.
  718. LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth);
  719. if (!regionp) return;
  720. renderHighlightSegments(mHighlightSegments, regionp);
  721. }
  722. }
  723. void LLViewerParcelMgr::renderParcelCollision()
  724. {
  725. // check for expiration
  726. if (mCollisionTimer.getElapsedTimeF32() > PARCEL_COLLISION_DRAW_SECS)
  727. {
  728. mRenderCollision = FALSE;
  729. }
  730. if (mRenderCollision && gSavedSettings.getBOOL("ShowBanLines"))
  731. {
  732. LLViewerRegion* regionp = gAgent.getRegion();
  733. if (regionp)
  734. {
  735. BOOL use_pass = mCollisionParcel->getParcelFlag(PF_USE_PASS_LIST);
  736. renderCollisionSegments(mCollisionSegments, use_pass, regionp);
  737. }
  738. }
  739. }
  740. void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags)
  741. {
  742. if (!mSelected)
  743. {
  744. return;
  745. }
  746. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  747. if (!region) return;
  748. LLMessageSystem *msg = gMessageSystem;
  749. if (flags & AL_BAN) 
  750. {
  751. mCurrentParcel->mBanList.clear();
  752. }
  753. if (flags & AL_ACCESS) 
  754. {
  755. mCurrentParcel->mAccessList.clear();
  756. }
  757. // Only the headers differ
  758. msg->newMessageFast(_PREHASH_ParcelAccessListRequest);
  759. msg->nextBlockFast(_PREHASH_AgentData);
  760. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
  761. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  762. msg->nextBlockFast(_PREHASH_Data);
  763. msg->addS32Fast(_PREHASH_SequenceID, 0);
  764. msg->addU32Fast(_PREHASH_Flags, flags);
  765. msg->addS32("LocalID", mCurrentParcel->getLocalID() );
  766. msg->sendReliable( region->getHost() );
  767. }
  768. void LLViewerParcelMgr::sendParcelDwellRequest()
  769. {
  770. if (!mSelected)
  771. {
  772. return;
  773. }
  774. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  775. if (!region) return;
  776. LLMessageSystem *msg = gMessageSystem;
  777. // Only the headers differ
  778. msg->newMessage("ParcelDwellRequest");
  779. msg->nextBlock("AgentData");
  780. msg->addUUID("AgentID", gAgent.getID() );
  781. msg->addUUID("SessionID", gAgent.getSessionID());
  782. msg->nextBlock("Data");
  783. msg->addS32("LocalID", mCurrentParcel->getLocalID());
  784. msg->addUUID("ParcelID", LLUUID::null); // filled in on simulator
  785. msg->sendReliable( region->getHost() );
  786. }
  787. void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
  788. {
  789. if (!mSelected)
  790. {
  791. LLNotificationsUtil::add("CannotSetLandOwnerNothingSelected");
  792. return;
  793. }
  794. llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
  795. // BUG: Only works for the region containing mWestSouthBottom
  796. LLVector3d east_north_region_check( mEastNorth );
  797. east_north_region_check.mdV[VX] -= 0.5;
  798. east_north_region_check.mdV[VY] -= 0.5;
  799. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  800. if (!region)
  801. {
  802. // TODO: Add a force owner version of this alert.
  803. LLNotificationsUtil::add("CannotContentifyNoRegion");
  804. return;
  805. }
  806. // BUG: Make work for cross-region selections
  807. LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
  808. if (region != region2)
  809. {
  810. LLNotificationsUtil::add("CannotSetLandOwnerMultipleRegions");
  811. return;
  812. }
  813. llinfos << "Region " << region->getOriginGlobal() << llendl;
  814. LLSD payload;
  815. payload["owner_id"] = owner_id;
  816. payload["parcel_local_id"] = mCurrentParcel->getLocalID();
  817. payload["region_host"] = region->getHost().getIPandPort();
  818. LLNotification::Params params("ForceOwnerAuctionWarning");
  819. params.payload(payload).functor.function(callback_god_force_owner);
  820. if(mCurrentParcel->getAuctionID())
  821. {
  822. LLNotifications::instance().add(params);
  823. }
  824. else
  825. {
  826. LLNotifications::instance().forceResponse(params, 0);
  827. }
  828. }
  829. bool callback_god_force_owner(const LLSD& notification, const LLSD& response)
  830. {
  831. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  832. if(0 == option)
  833. {
  834. LLMessageSystem* msg = gMessageSystem;
  835. msg->newMessage("ParcelGodForceOwner");
  836. msg->nextBlock("AgentData");
  837. msg->addUUID("AgentID", gAgent.getID());
  838. msg->addUUID("SessionID", gAgent.getSessionID());
  839. msg->nextBlock("Data");
  840. msg->addUUID("OwnerID", notification["payload"]["owner_id"].asUUID());
  841. msg->addS32( "LocalID", notification["payload"]["parcel_local_id"].asInteger());
  842. msg->sendReliable(LLHost(notification["payload"]["region_host"].asString()));
  843. }
  844. return false;
  845. }
  846. void LLViewerParcelMgr::sendParcelGodForceToContent()
  847. {
  848. if (!mSelected)
  849. {
  850. LLNotificationsUtil::add("CannotContentifyNothingSelected");
  851. return;
  852. }
  853. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  854. if (!region)
  855. {
  856. LLNotificationsUtil::add("CannotContentifyNoRegion");
  857. return;
  858. }
  859. LLMessageSystem* msg = gMessageSystem;
  860. msg->newMessage("ParcelGodMarkAsContent");
  861. msg->nextBlock("AgentData");
  862. msg->addUUID("AgentID", gAgent.getID());
  863. msg->addUUID("SessionID", gAgent.getSessionID());
  864. msg->nextBlock("ParcelData");
  865. msg->addS32("LocalID", mCurrentParcel->getLocalID());
  866. msg->sendReliable(region->getHost());
  867. }
  868. void LLViewerParcelMgr::sendParcelRelease()
  869. {
  870. if (!mSelected)
  871. {
  872.         LLNotificationsUtil::add("CannotReleaseLandNothingSelected");
  873. return;
  874. }
  875. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  876. if (!region)
  877. {
  878. LLNotificationsUtil::add("CannotReleaseLandNoRegion");
  879. return;
  880. }
  881. //U32 flags = PR_NONE;
  882. //if (god_force) flags |= PR_GOD_FORCE;
  883. LLMessageSystem* msg = gMessageSystem;
  884. msg->newMessage("ParcelRelease");
  885. msg->nextBlock("AgentData");
  886. msg->addUUID("AgentID", gAgent.getID() );
  887. msg->addUUID("SessionID", gAgent.getSessionID() );
  888. msg->nextBlock("Data");
  889. msg->addS32("LocalID", mCurrentParcel->getLocalID() );
  890. //msg->addU32("Flags", flags);
  891. msg->sendReliable( region->getHost() );
  892. // Blitz selection, since the parcel might be non-rectangular, and
  893. // we won't have appropriate parcel information.
  894. deselectLand();
  895. }
  896. class LLViewerParcelMgr::ParcelBuyInfo
  897. {
  898. public:
  899. LLUUID mAgent;
  900. LLUUID mSession;
  901. LLUUID mGroup;
  902. BOOL mIsGroupOwned;
  903. BOOL mRemoveContribution;
  904. BOOL mIsClaim;
  905. LLHost mHost;
  906. // for parcel buys
  907. S32 mParcelID;
  908. S32 mPrice;
  909. S32 mArea;
  910. // for land claims
  911. F32 mWest;
  912. F32 mSouth;
  913. F32 mEast;
  914. F32 mNorth;
  915. };
  916. LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
  917. const LLUUID& agent_id,
  918. const LLUUID& session_id,
  919. const LLUUID& group_id,
  920. BOOL is_group_owned,
  921. BOOL is_claim,
  922. BOOL remove_contribution)
  923. {
  924. if (!mSelected || !mCurrentParcel)
  925. {
  926. LLNotificationsUtil::add("CannotBuyLandNothingSelected");
  927. return NULL;
  928. }
  929. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  930. if (!region)
  931. {
  932. LLNotificationsUtil::add("CannotBuyLandNoRegion");
  933. return NULL;
  934. }
  935. if (is_claim)
  936. {
  937. llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
  938. llinfos << "Region " << region->getOriginGlobal() << llendl;
  939. // BUG: Only works for the region containing mWestSouthBottom
  940. LLVector3d east_north_region_check( mEastNorth );
  941. east_north_region_check.mdV[VX] -= 0.5;
  942. east_north_region_check.mdV[VY] -= 0.5;
  943. LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
  944. if (region != region2)
  945. {
  946. LLNotificationsUtil::add("CantBuyLandAcrossMultipleRegions");
  947. return NULL;
  948. }
  949. }
  950. ParcelBuyInfo* info = new ParcelBuyInfo;
  951. info->mAgent = agent_id;
  952. info->mSession = session_id;
  953. info->mGroup = group_id;
  954. info->mIsGroupOwned = is_group_owned;
  955. info->mIsClaim = is_claim;
  956. info->mRemoveContribution = remove_contribution;
  957. info->mHost = region->getHost();
  958. info->mPrice = mCurrentParcel->getSalePrice();
  959. info->mArea = mCurrentParcel->getArea();
  960. if (!is_claim)
  961. {
  962. info->mParcelID = mCurrentParcel->getLocalID();
  963. }
  964. else
  965. {
  966. // BUG: Make work for cross-region selections
  967. LLVector3 west_south_bottom_region = region->getPosRegionFromGlobal( mWestSouth );
  968. LLVector3 east_north_top_region = region->getPosRegionFromGlobal( mEastNorth );
  969. info->mWest = west_south_bottom_region.mV[VX];
  970. info->mSouth = west_south_bottom_region.mV[VY];
  971. info->mEast = east_north_top_region.mV[VX];
  972. info->mNorth = east_north_top_region.mV[VY];
  973. }
  974. return info;
  975. }
  976. void LLViewerParcelMgr::sendParcelBuy(ParcelBuyInfo* info)
  977. {
  978. // send the message
  979. LLMessageSystem* msg = gMessageSystem;
  980. msg->newMessage(info->mIsClaim ? "ParcelClaim" : "ParcelBuy");
  981. msg->nextBlock("AgentData");
  982. msg->addUUID("AgentID", info->mAgent);
  983. msg->addUUID("SessionID", info->mSession);
  984. msg->nextBlock("Data");
  985. msg->addUUID("GroupID", info->mGroup);
  986. msg->addBOOL("IsGroupOwned", info->mIsGroupOwned);
  987. if (!info->mIsClaim)
  988. {
  989. msg->addBOOL("RemoveContribution", info->mRemoveContribution);
  990. msg->addS32("LocalID", info->mParcelID);
  991. }
  992. msg->addBOOL("Final", TRUE); // don't allow escrow buys
  993. if (info->mIsClaim)
  994. {
  995. msg->nextBlock("ParcelData");
  996. msg->addF32("West",  info->mWest);
  997. msg->addF32("South", info->mSouth);
  998. msg->addF32("East",  info->mEast);
  999. msg->addF32("North", info->mNorth);
  1000. }
  1001. else // ParcelBuy
  1002. {
  1003. msg->nextBlock("ParcelData");
  1004. msg->addS32("Price",info->mPrice);
  1005. msg->addS32("Area",info->mArea);
  1006. }
  1007. msg->sendReliable(info->mHost);
  1008. }
  1009. void LLViewerParcelMgr::deleteParcelBuy(ParcelBuyInfo* *info)
  1010. {
  1011. // Must be here because ParcelBuyInfo is local to this .cpp file
  1012. delete *info;
  1013. *info = NULL;
  1014. }
  1015. void LLViewerParcelMgr::sendParcelDeed(const LLUUID& group_id)
  1016. {
  1017. if (!mSelected || !mCurrentParcel)
  1018. {
  1019. LLNotificationsUtil::add("CannotDeedLandNothingSelected");
  1020. return;
  1021. }
  1022. if(group_id.isNull())
  1023. {
  1024. LLNotificationsUtil::add("CannotDeedLandNoGroup");
  1025. return;
  1026. }
  1027. LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  1028. if (!region)
  1029. {
  1030. LLNotificationsUtil::add("CannotDeedLandNoRegion");
  1031. return;
  1032. }
  1033. LLMessageSystem* msg = gMessageSystem;
  1034. msg->newMessage("ParcelDeedToGroup");
  1035. msg->nextBlock("AgentData");
  1036. msg->addUUID("AgentID", gAgent.getID() );
  1037. msg->addUUID("SessionID", gAgent.getSessionID() );
  1038. msg->nextBlock("Data");
  1039. msg->addUUID("GroupID", group_id );
  1040. msg->addS32("LocalID", mCurrentParcel->getLocalID() );
  1041. //msg->addU32("JoinNeighbors", join);
  1042. msg->sendReliable( region->getHost() );
  1043. }
  1044. /*
  1045. // *NOTE: We cannot easily make landmarks at global positions because
  1046. // global positions probably refer to a sim/local combination which
  1047. // can move over time. We could implement this by looking up the
  1048. // region global x,y, but it's easier to take it out for now.
  1049. void LLViewerParcelMgr::makeLandmarkAtSelection()
  1050. {
  1051. // Don't create for parcels you don't own
  1052. if (gAgent.getID() != mCurrentParcel->getOwnerID())
  1053. {
  1054. return;
  1055. }
  1056. LLVector3d global_center(mWestSouth);
  1057. global_center += mEastNorth;
  1058. global_center *= 0.5f;
  1059. LLViewerRegion* region;
  1060. region = LLWorld::getInstance()->getRegionFromPosGlobal(global_center);
  1061. LLVector3 west_south_bottom_region = region->getPosRegionFromGlobal( mWestSouth );
  1062. LLVector3 east_north_top_region = region->getPosRegionFromGlobal( mEastNorth );
  1063. std::string name("My Land");
  1064. std::string buffer;
  1065. S32 pos_x = (S32)floor((west_south_bottom_region.mV[VX] + east_north_top_region.mV[VX]) / 2.0f);
  1066. S32 pos_y = (S32)floor((west_south_bottom_region.mV[VY] + east_north_top_region.mV[VY]) / 2.0f);
  1067. buffer = llformat("%s in %s (%d, %d)",
  1068. name.c_str(),
  1069. region->getName().c_str(),
  1070. pos_x, pos_y);
  1071. name.assign(buffer);
  1072. create_landmark(name, "Claimed land", global_center);
  1073. }
  1074. */
  1075. const std::string& LLViewerParcelMgr::getAgentParcelName() const
  1076. {
  1077. return mAgentParcel->getName();
  1078. }
  1079. void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
  1080. {
  1081. if(!parcel) return;
  1082. LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  1083. if (!region) return;
  1084. //llinfos << "found region: " << region->getName() << llendl;
  1085. LLSD body;
  1086. std::string url = region->getCapability("ParcelPropertiesUpdate");
  1087. if (!url.empty())
  1088. {
  1089. // request new properties update from simulator
  1090. U32 message_flags = 0x01;
  1091. body["flags"] = ll_sd_from_U32(message_flags);
  1092. parcel->packMessage(body);
  1093. llinfos << "Sending parcel properties update via capability to: "
  1094. << url << llendl;
  1095. LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
  1096. }
  1097. else
  1098. {
  1099. LLMessageSystem* msg = gMessageSystem;
  1100. msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate);
  1101. msg->nextBlockFast(_PREHASH_AgentData);
  1102. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  1103. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
  1104. msg->nextBlockFast(_PREHASH_ParcelData);
  1105. msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
  1106. U32 message_flags = 0x01;
  1107. msg->addU32("Flags", message_flags);
  1108. parcel->packMessage(msg);
  1109. msg->sendReliable( region->getHost() );
  1110. }
  1111. }
  1112. void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
  1113. {
  1114. static U32 last_west, last_south;
  1115. // only request parcel info when tooltip is shown
  1116. if (!gSavedSettings.getBOOL("ShowLandHoverTip"))
  1117. {
  1118. return;
  1119. }
  1120. // only request parcel info if position has changed outside of the
  1121. // last parcel grid step
  1122. U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
  1123. U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
  1124. if ((west_parcel_step == last_west) && (south_parcel_step == last_south))
  1125. {
  1126. return;
  1127. }
  1128. else 
  1129. {
  1130. last_west = west_parcel_step;
  1131. last_south = south_parcel_step;
  1132. }
  1133. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos );
  1134. if (!region)
  1135. {
  1136. return;
  1137. }
  1138. // Send a rectangle around the point.
  1139. // This means the parcel sent back is at least a rectangle around the point,
  1140. // which is more efficient for public land.  Fewer requests are sent.  JC
  1141. LLVector3 wsb_region = region->getPosRegionFromGlobal( pos );
  1142. F32 west  = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS );
  1143. F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS );
  1144. F32 east  = west  + PARCEL_GRID_STEP_METERS;
  1145. F32 north = south + PARCEL_GRID_STEP_METERS;
  1146. // Send request message
  1147. LLMessageSystem *msg = gMessageSystem;
  1148. msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
  1149. msg->nextBlockFast(_PREHASH_AgentData);
  1150. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  1151. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  1152. msg->nextBlockFast(_PREHASH_ParcelData);
  1153. msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID );
  1154. msg->addF32Fast(_PREHASH_West, west );
  1155. msg->addF32Fast(_PREHASH_South, south );
  1156. msg->addF32Fast(_PREHASH_East, east );
  1157. msg->addF32Fast(_PREHASH_North, north );
  1158. msg->addBOOL("SnapSelection", FALSE );
  1159. msg->sendReliable( region->getHost() );
  1160. mHoverRequestResult = PARCEL_RESULT_NO_DATA;
  1161. }
  1162. // static
  1163. void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
  1164. {
  1165. if (gNoRender)
  1166. {
  1167. return;
  1168. }
  1169. // Extract the packed overlay information
  1170. S32 packed_overlay_size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Data);
  1171. if (packed_overlay_size <= 0)
  1172. {
  1173. llwarns << "Overlay size " << packed_overlay_size << llendl;
  1174. return;
  1175. }
  1176. S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge;
  1177. S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
  1178. if (packed_overlay_size != expected_size)
  1179. {
  1180. llwarns << "Got parcel overlay size " << packed_overlay_size
  1181. << " expecting " << expected_size << llendl;
  1182. return;
  1183. }
  1184. S32 sequence_id;
  1185. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id);
  1186. msg->getBinaryDataFast(
  1187. _PREHASH_ParcelData,
  1188. _PREHASH_Data,
  1189. sPackedOverlay,
  1190. expected_size);
  1191. LLHost host = msg->getSender();
  1192. LLViewerRegion *region = LLWorld::getInstance()->getRegion(host);
  1193. if (region)
  1194. {
  1195. region->mParcelOverlay->uncompressLandOverlay( sequence_id, sPackedOverlay );
  1196. }
  1197. }
  1198. // static
  1199. void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
  1200. {
  1201. S32 request_result;
  1202. S32 sequence_id;
  1203. BOOL snap_selection = FALSE;
  1204. S32 self_count = 0;
  1205. S32 other_count = 0;
  1206. S32 public_count = 0;
  1207. S32 local_id;
  1208. LLUUID owner_id;
  1209. BOOL is_group_owned;
  1210. U32 auction_id = 0;
  1211. S32 claim_price_per_meter = 0;
  1212. S32 rent_price_per_meter = 0;
  1213. S32 claim_date = 0;
  1214. LLVector3 aabb_min;
  1215. LLVector3 aabb_max;
  1216. S32 area = 0;
  1217. S32 sw_max_prims = 0;
  1218. S32 sw_total_prims = 0;
  1219. //LLUUID buyer_id;
  1220. U8 status = 0;
  1221. S32 max_prims = 0;
  1222. S32 total_prims = 0;
  1223. S32 owner_prims = 0;
  1224. S32 group_prims = 0;
  1225. S32 other_prims = 0;
  1226. S32 selected_prims = 0;
  1227. F32 parcel_prim_bonus = 1.f;
  1228. BOOL region_push_override = false;
  1229. BOOL region_deny_anonymous_override = false;
  1230. BOOL region_deny_identified_override = false; // Deprecated
  1231. BOOL region_deny_transacted_override = false; // Deprecated
  1232. BOOL region_deny_age_unverified_override = false;
  1233. S32 other_clean_time = 0;
  1234. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
  1235. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
  1236. if (request_result == PARCEL_RESULT_NO_DATA)
  1237. {
  1238. // no valid parcel data
  1239. llinfos << "no valid parcel data" << llendl;
  1240. return;
  1241. }
  1242. // Decide where the data will go.
  1243. LLParcel* parcel = NULL;
  1244. if (sequence_id == SELECTED_PARCEL_SEQ_ID)
  1245. {
  1246. // ...selected parcels report this sequence id
  1247. LLViewerParcelMgr::getInstance()->mRequestResult = PARCEL_RESULT_SUCCESS;
  1248. parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
  1249. }
  1250. else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
  1251. {
  1252. LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
  1253. parcel = LLViewerParcelMgr::getInstance()->mHoverParcel;
  1254. }
  1255. else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
  1256.  sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
  1257.  sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
  1258. {
  1259. LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
  1260. parcel = LLViewerParcelMgr::getInstance()->mCollisionParcel;
  1261. }
  1262. else if (sequence_id == 0 || sequence_id > LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID)
  1263. {
  1264. // new agent parcel
  1265. LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID = sequence_id;
  1266. parcel = LLViewerParcelMgr::getInstance()->mAgentParcel;
  1267. }
  1268. else
  1269. {
  1270. llinfos << "out of order agent parcel sequence id " << sequence_id
  1271. << " last good " << LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID
  1272. << llendl;
  1273. return;
  1274. }
  1275. msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
  1276. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
  1277. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
  1278. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
  1279. msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_LocalID, local_id );
  1280. msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
  1281. msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
  1282. msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
  1283. msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
  1284. msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
  1285. msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
  1286. msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
  1287. msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
  1288. msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_Area, area );
  1289. //msg->getUUIDFast( _PREHASH_ParcelData, _PREHASH_BuyerID, buyer_id);
  1290. msg->getU8("ParcelData", "Status", status);
  1291. msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims );
  1292. msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims );
  1293. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims );
  1294. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims );
  1295. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims );
  1296. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims );
  1297. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims );
  1298. msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims );
  1299. msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus );
  1300. msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override );
  1301. msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override );
  1302. msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override ); // Deprecated
  1303. msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override ); // Deprecated
  1304. if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
  1305. {
  1306. // this block was added later and may not be on older sims, so we have to test its existence first
  1307. msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override );
  1308. }
  1309. msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
  1310. // Actually extract the data.
  1311. if (parcel)
  1312. {
  1313. parcel->init(owner_id,
  1314. FALSE, FALSE, FALSE,
  1315. claim_date, claim_price_per_meter, rent_price_per_meter,
  1316. area, other_prims, parcel_prim_bonus, is_group_owned);
  1317. parcel->setLocalID(local_id);
  1318. parcel->setAABBMin(aabb_min);
  1319. parcel->setAABBMax(aabb_max);
  1320. parcel->setAuctionID(auction_id);
  1321. parcel->setOwnershipStatus((LLParcel::EOwnershipStatus)status);
  1322. parcel->setSimWideMaxPrimCapacity(sw_max_prims);
  1323. parcel->setSimWidePrimCount(sw_total_prims);
  1324. parcel->setMaxPrimCapacity(max_prims);
  1325. parcel->setOwnerPrimCount(owner_prims);
  1326. parcel->setGroupPrimCount(group_prims);
  1327. parcel->setOtherPrimCount(other_prims);
  1328. parcel->setSelectedPrimCount(selected_prims);
  1329. parcel->setParcelPrimBonus(parcel_prim_bonus);
  1330. parcel->setCleanOtherTime(other_clean_time);
  1331. parcel->setRegionPushOverride(region_push_override);
  1332. parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
  1333. parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override);
  1334. parcel->unpackMessage(msg);
  1335. if (parcel == LLViewerParcelMgr::getInstance()->mAgentParcel)
  1336. {
  1337. S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1338. * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1339. / 8;
  1340. U8* bitmap = new U8[ bitmap_size ];
  1341. msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
  1342. LLViewerParcelMgr::getInstance()->writeAgentParcelFromBitmap(bitmap);
  1343. delete[] bitmap;
  1344. // Let interesting parties know about agent parcel change.
  1345. LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance();
  1346. instance->mAgentParcelChangedSignal();
  1347. if (instance->mTeleportInProgress)
  1348. {
  1349. instance->mTeleportInProgress = FALSE;
  1350. instance->mTeleportFinishedSignal(gAgent.getPositionGlobal());
  1351. }
  1352. }
  1353. }
  1354. // Handle updating selections, if necessary.
  1355. if (sequence_id == SELECTED_PARCEL_SEQ_ID)
  1356. {
  1357. // Update selected counts
  1358. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedSelfCount = self_count;
  1359. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedOtherCount = other_count;
  1360. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedPublicCount = public_count;
  1361. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedMultipleOwners =
  1362. (request_result == PARCEL_RESULT_MULTIPLE);
  1363. // Select the whole parcel
  1364. LLViewerRegion* region = LLWorld::getInstance()->getRegion( msg->getSender() );
  1365. if (region)
  1366. {
  1367. if (!snap_selection)
  1368. {
  1369. // don't muck with the westsouth and eastnorth.
  1370. // just highlight it
  1371. LLVector3 west_south = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mWestSouth);
  1372. LLVector3 east_north = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mEastNorth);
  1373. LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
  1374. LLViewerParcelMgr::getInstance()->writeHighlightSegments(
  1375. west_south.mV[VX],
  1376. west_south.mV[VY],
  1377. east_north.mV[VX],
  1378. east_north.mV[VY] );
  1379. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = FALSE;
  1380. }
  1381. else if (0 == local_id)
  1382. {
  1383. // this is public land, just highlight the selection
  1384. LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
  1385. LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
  1386. LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
  1387. LLViewerParcelMgr::getInstance()->writeHighlightSegments(
  1388. aabb_min.mV[VX],
  1389. aabb_min.mV[VY],
  1390. aabb_max.mV[VX],
  1391. aabb_max.mV[VY] );
  1392. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
  1393. }
  1394. else
  1395. {
  1396. LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
  1397. LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
  1398. // Owned land, highlight the boundaries
  1399. S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1400. * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1401. / 8;
  1402. U8* bitmap = new U8[ bitmap_size ];
  1403. msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
  1404. LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
  1405. LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mHighlightSegments );
  1406. delete[] bitmap;
  1407. bitmap = NULL;
  1408. LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
  1409. }
  1410. // Request access list information for this land
  1411. LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
  1412. // Request the media url filter list for this land
  1413. LLViewerParcelMgr::getInstance()->requestParcelMediaURLFilter();
  1414. // Request dwell for this land, if it's not public land.
  1415. LLViewerParcelMgr::getInstance()->mSelectedDwell = 0.f;
  1416. if (0 != local_id)
  1417. {
  1418. LLViewerParcelMgr::getInstance()->sendParcelDwellRequest();
  1419. }
  1420. LLViewerParcelMgr::getInstance()->mSelected = TRUE;
  1421. LLViewerParcelMgr::getInstance()->notifyObservers();
  1422. }
  1423. }
  1424. else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
  1425.  sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID  ||
  1426.  sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
  1427. {
  1428. // We're about to collide with this parcel
  1429. LLViewerParcelMgr::getInstance()->mRenderCollision = TRUE;
  1430. LLViewerParcelMgr::getInstance()->mCollisionTimer.reset();
  1431. // Differentiate this parcel if we are banned from it.
  1432. if (sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
  1433. {
  1434. LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_BANNED;
  1435. }
  1436. else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID)
  1437. {
  1438. LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_IN_GROUP;
  1439. }
  1440. else 
  1441. {
  1442. LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_ON_LIST;
  1443. }
  1444. S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1445. * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
  1446. / 8;
  1447. U8* bitmap = new U8[ bitmap_size ];
  1448. msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
  1449. LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mCollisionSegments);
  1450. LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mCollisionSegments );
  1451. delete[] bitmap;
  1452. bitmap = NULL;
  1453. }
  1454. else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
  1455. {
  1456. LLViewerRegion *region = LLWorld::getInstance()->getRegion( msg->getSender() );
  1457. if (region)
  1458. {
  1459. LLViewerParcelMgr::getInstance()->mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min );
  1460. LLViewerParcelMgr::getInstance()->mHoverEastNorth = region->getPosGlobalFromRegion( aabb_max );
  1461. }
  1462. else
  1463. {
  1464. LLViewerParcelMgr::getInstance()->mHoverWestSouth.clearVec();
  1465. LLViewerParcelMgr::getInstance()->mHoverEastNorth.clearVec();
  1466. }
  1467. }
  1468. else
  1469. {
  1470. // look for music.
  1471. if (gAudiop)
  1472. {
  1473. if (parcel)
  1474. {
  1475. std::string music_url_raw = parcel->getMusicURL();
  1476. // Trim off whitespace from front and back
  1477. std::string music_url = music_url_raw;
  1478. LLStringUtil::trim(music_url);
  1479. // On entering a new parcel, stop the last stream if the
  1480. // new parcel has a different music url.  (Empty URL counts
  1481. // as different.)
  1482. const std::string& stream_url = gAudiop->getInternetStreamURL();
  1483. if (music_url.empty() || music_url != stream_url)
  1484. {
  1485. // URL is different from one currently playing.
  1486. gAudiop->stopInternetStream();
  1487. // If there is a new music URL and it's valid, play it.
  1488. if (music_url.size() > 12)
  1489. {
  1490. if (music_url.substr(0,7) == "http://")
  1491. {
  1492. optionally_start_music(music_url);
  1493. }
  1494. else
  1495. {
  1496. llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
  1497. // clears the URL 
  1498. gAudiop->startInternetStream(LLStringUtil::null); 
  1499. }
  1500. }
  1501. else if (!gAudiop->getInternetStreamURL().empty())
  1502. {
  1503. llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
  1504. gAudiop->startInternetStream(LLStringUtil::null);
  1505. }
  1506. }
  1507. }
  1508. else
  1509. {
  1510. // Public land has no music
  1511. gAudiop->stopInternetStream();
  1512. }
  1513. }//if gAudiop
  1514. // now check for video
  1515. LLViewerParcelMedia::update( parcel );
  1516. };
  1517. }
  1518. void optionally_start_music(const std::string& music_url)
  1519. {
  1520. if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
  1521.     gSavedSettings.getBOOL("AudioStreamingMedia"))
  1522. {
  1523. // only play music when you enter a new parcel if the UI control for this
  1524. // was not *explicitly* stopped by the user. (part of SL-4878)
  1525. LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();;
  1526. if ((nearby_media_panel &&
  1527.      nearby_media_panel->getParcelAudioAutoStart()) ||
  1528.     // or they have expressed no opinion in the UI, but have autoplay on...
  1529.     (!nearby_media_panel &&
  1530.      gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
  1531.  gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
  1532. {
  1533. llinfos << "Starting parcel music " << music_url << llendl;
  1534. gAudiop->startInternetStream(music_url);
  1535. }
  1536. }
  1537. }
  1538. // static
  1539. void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user)
  1540. {
  1541. LLUUID agent_id;
  1542. S32 sequence_id = 0;
  1543. U32 message_flags = 0x0;
  1544. S32 parcel_id = -1;
  1545. msg->getUUIDFast(_PREHASH_Data, _PREHASH_AgentID, agent_id);
  1546. msg->getS32Fast( _PREHASH_Data, _PREHASH_SequenceID, sequence_id ); //ignored
  1547. msg->getU32Fast( _PREHASH_Data, _PREHASH_Flags, message_flags);
  1548. msg->getS32Fast( _PREHASH_Data, _PREHASH_LocalID, parcel_id);
  1549. LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
  1550. if (!parcel) return;
  1551. if (parcel_id != parcel->getLocalID())
  1552. {
  1553. LL_WARNS_ONCE("") << "processParcelAccessListReply for parcel " << parcel_id
  1554. << " which isn't the selected parcel " << parcel->getLocalID()<< llendl;
  1555. return;
  1556. }
  1557. if (message_flags & AL_ACCESS)
  1558. {
  1559. parcel->unpackAccessEntries(msg, &(parcel->mAccessList) );
  1560. }
  1561. else if (message_flags & AL_BAN)
  1562. {
  1563. parcel->unpackAccessEntries(msg, &(parcel->mBanList) );
  1564. }
  1565. /*else if (message_flags & AL_RENTER)
  1566. {
  1567. parcel->unpackAccessEntries(msg, &(parcel->mRenterList) );
  1568. }*/
  1569. LLViewerParcelMgr::getInstance()->notifyObservers();
  1570. }
  1571. // static
  1572. void LLViewerParcelMgr::processParcelDwellReply(LLMessageSystem* msg, void**)
  1573. {
  1574. LLUUID agent_id;
  1575. msg->getUUID("AgentData", "AgentID", agent_id);
  1576. S32 local_id;
  1577. msg->getS32("Data", "LocalID", local_id);
  1578. LLUUID parcel_id;
  1579. msg->getUUID("Data", "ParcelID", parcel_id);
  1580. F32 dwell;
  1581. msg->getF32("Data", "Dwell", dwell);
  1582. if (local_id == LLViewerParcelMgr::getInstance()->mCurrentParcel->getLocalID())
  1583. {
  1584. LLViewerParcelMgr::getInstance()->mSelectedDwell = dwell;
  1585. LLViewerParcelMgr::getInstance()->notifyObservers();
  1586. }
  1587. }
  1588. void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
  1589. {
  1590. LLUUID transactionUUID;
  1591. transactionUUID.generate();
  1592. if (!mSelected)
  1593. {
  1594. return;
  1595. }
  1596. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  1597. if (!region) return;
  1598. LLMessageSystem* msg = gMessageSystem;
  1599. LLParcel* parcel = mCurrentParcel;
  1600. if (!parcel) return;
  1601. if (which & AL_ACCESS)
  1602. {
  1603. S32 count = parcel->mAccessList.size();
  1604. S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
  1605. S32 sequence_id = 1;
  1606. BOOL start_message = TRUE;
  1607. BOOL initial = TRUE;
  1608. access_map_const_iterator cit = parcel->mAccessList.begin();
  1609. access_map_const_iterator end = parcel->mAccessList.end();
  1610. while ( (cit != end) || initial ) 
  1611. {
  1612. if (start_message) 
  1613. {
  1614. msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
  1615. msg->nextBlockFast(_PREHASH_AgentData);
  1616. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  1617. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  1618. msg->nextBlockFast(_PREHASH_Data);
  1619. msg->addU32Fast(_PREHASH_Flags, AL_ACCESS);
  1620. msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
  1621. msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
  1622. msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
  1623. msg->addS32Fast(_PREHASH_Sections, num_sections);
  1624. start_message = FALSE;
  1625. if (initial && (cit == end))
  1626. {
  1627. // pack an empty block if there will be no data
  1628. msg->nextBlockFast(_PREHASH_List);
  1629. msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
  1630. msg->addS32Fast(_PREHASH_Time, 0 );
  1631. msg->addU32Fast(_PREHASH_Flags, 0 );
  1632. }
  1633. initial = FALSE;
  1634. sequence_id++;
  1635. }
  1636. while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES)) 
  1637. {
  1638. const LLAccessEntry& entry = (*cit).second;
  1639. msg->nextBlockFast(_PREHASH_List);
  1640. msg->addUUIDFast(_PREHASH_ID,  entry.mID );
  1641. msg->addS32Fast(_PREHASH_Time, entry.mTime );
  1642. msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
  1643. ++cit;
  1644. }
  1645. start_message = TRUE;
  1646. msg->sendReliable( region->getHost() );
  1647. }
  1648. }
  1649. if (which & AL_BAN)
  1650. {
  1651. S32 count = parcel->mBanList.size();
  1652. S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
  1653. S32 sequence_id = 1;
  1654. BOOL start_message = TRUE;
  1655. BOOL initial = TRUE;
  1656. access_map_const_iterator cit = parcel->mBanList.begin();
  1657. access_map_const_iterator end = parcel->mBanList.end();
  1658. while ( (cit != end) || initial ) 
  1659. {
  1660. if (start_message) 
  1661. {
  1662. msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
  1663. msg->nextBlockFast(_PREHASH_AgentData);
  1664. msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
  1665. msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
  1666. msg->nextBlockFast(_PREHASH_Data);
  1667. msg->addU32Fast(_PREHASH_Flags, AL_BAN);
  1668. msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
  1669. msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
  1670. msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
  1671. msg->addS32Fast(_PREHASH_Sections, num_sections);
  1672. start_message = FALSE;
  1673. if (initial && (cit == end))
  1674. {
  1675. // pack an empty block if there will be no data
  1676. msg->nextBlockFast(_PREHASH_List);
  1677. msg->addUUIDFast(_PREHASH_ID,  LLUUID::null );
  1678. msg->addS32Fast(_PREHASH_Time, 0 );
  1679. msg->addU32Fast(_PREHASH_Flags, 0 );
  1680. }
  1681. initial = FALSE;
  1682. sequence_id++;
  1683. }
  1684. while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES)) 
  1685. {
  1686. const LLAccessEntry& entry = (*cit).second;
  1687. msg->nextBlockFast(_PREHASH_List);
  1688. msg->addUUIDFast(_PREHASH_ID,  entry.mID );
  1689. msg->addS32Fast(_PREHASH_Time, entry.mTime );
  1690. msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
  1691. ++cit;
  1692. }
  1693. start_message = TRUE;
  1694. msg->sendReliable( region->getHost() );
  1695. }
  1696. }
  1697. }
  1698. class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder
  1699. {
  1700. virtual void result(const LLSD& content)
  1701. {
  1702. LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content);
  1703. }
  1704. };
  1705. void LLViewerParcelMgr::requestParcelMediaURLFilter()
  1706. {
  1707. if (!mSelected)
  1708. {
  1709. return;
  1710. }
  1711. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
  1712. if (!region)
  1713. {
  1714. return;
  1715. }
  1716. LLParcel* parcel = mCurrentParcel;
  1717. if (!parcel)
  1718. {
  1719. llwarns << "no parcel" << llendl;
  1720. return;
  1721. }
  1722. LLSD body;
  1723. body["local-id"] = parcel->getLocalID();
  1724. body["list"] = parcel->getMediaURLFilterList();
  1725. std::string url = region->getCapability("ParcelMediaURLFilterList");
  1726. if (!url.empty())
  1727. {
  1728. LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder);
  1729. }
  1730. else
  1731. {
  1732. llwarns << "can't get ParcelMediaURLFilterList cap" << llendl;
  1733. }
  1734. }
  1735. void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content)
  1736. {
  1737. if (content.has("list"))
  1738. {
  1739. LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
  1740. if (!parcel) return;
  1741. if (content["local-id"].asInteger() == parcel->getLocalID())
  1742. {
  1743. parcel->setMediaURLFilterList(content["list"]);
  1744. LLViewerParcelMgr::getInstance()->notifyObservers();
  1745. }
  1746. }
  1747. }
  1748. void LLViewerParcelMgr::deedLandToGroup()
  1749. {
  1750. std::string group_name;
  1751. gCacheName->getGroupName(mCurrentParcel->getGroupID(), group_name);
  1752. LLSD args;
  1753. args["AREA"] = llformat("%d", mCurrentParcel->getArea());
  1754. args["GROUP_NAME"] = group_name;
  1755. if(mCurrentParcel->getContributeWithDeed())
  1756. {
  1757. std::string first_name, last_name;
  1758. gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name);
  1759. args["FIRST_NAME"] = first_name;
  1760. args["LAST_NAME"] = last_name;
  1761. LLNotificationsUtil::add("DeedLandToGroupWithContribution",args, LLSD(), deedAlertCB);
  1762. }
  1763. else
  1764. {
  1765. LLNotificationsUtil::add("DeedLandToGroup",args, LLSD(), deedAlertCB);
  1766. }
  1767. }
  1768. // static
  1769. bool LLViewerParcelMgr::deedAlertCB(const LLSD& notification, const LLSD& response)
  1770. {
  1771. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1772. if (option == 0)
  1773. {
  1774. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
  1775. LLUUID group_id;
  1776. if(parcel)
  1777. {
  1778. group_id = parcel->getGroupID();
  1779. }
  1780. LLViewerParcelMgr::getInstance()->sendParcelDeed(group_id);
  1781. }
  1782. return false;
  1783. }
  1784. void LLViewerParcelMgr::startReleaseLand()
  1785. {
  1786. if (!mSelected)
  1787. {
  1788. LLNotificationsUtil::add("CannotReleaseLandNothingSelected");
  1789. return;
  1790. }
  1791. if (mRequestResult == PARCEL_RESULT_NO_DATA)
  1792. {
  1793. LLNotificationsUtil::add("CannotReleaseLandWatingForServer");
  1794. return;
  1795. }
  1796. if (mRequestResult == PARCEL_RESULT_MULTIPLE)
  1797. {
  1798. LLNotificationsUtil::add("CannotReleaseLandSelected");
  1799. return;
  1800. }
  1801. if (!isParcelOwnedByAgent(mCurrentParcel, GP_LAND_RELEASE)
  1802. && !(gAgent.canManageEstate()))
  1803. {
  1804. LLNotificationsUtil::add("CannotReleaseLandDontOwn");
  1805. return;
  1806. }
  1807. LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
  1808. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
  1809. if (!region)
  1810. {
  1811. LLNotificationsUtil::add("CannotReleaseLandRegionNotFound");
  1812. return;
  1813. }
  1814. /*
  1815. if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
  1816. && !gAgent.isGodlike())
  1817. {
  1818. LLSD args;
  1819. args["REGION"] = region->getName();
  1820. LLNotificationsUtil::add("CannotReleaseLandNoTransfer", args);
  1821. return;
  1822. }
  1823. */
  1824. if (!mCurrentParcelSelection->mWholeParcelSelected)
  1825. {
  1826. LLNotificationsUtil::add("CannotReleaseLandPartialSelection");
  1827. return;
  1828. }
  1829. // Compute claim price
  1830. LLSD args;
  1831. args["AREA"] = llformat("%d",mCurrentParcel->getArea());
  1832. LLNotificationsUtil::add("ReleaseLandWarning", args, LLSD(), releaseAlertCB);
  1833. }
  1834. bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
  1835. {
  1836. if (!parcel)
  1837. {
  1838. return false;
  1839. }
  1840. if (mSelected  &&  parcel == mCurrentParcel)
  1841. {
  1842. if (mRequestResult == PARCEL_RESULT_NO_DATA)
  1843. {
  1844. return false;
  1845. }
  1846. }
  1847. const LLUUID& parcelOwner = parcel->getOwnerID();
  1848. const LLUUID& authorizeBuyer = parcel->getAuthorizedBuyerID();
  1849. if (parcel->isPublic())
  1850. {
  1851. return true; // change this if want to make it gods only
  1852. }
  1853. LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  1854. if (regionp)
  1855. {
  1856. U8 sim_access = regionp->getSimAccess();
  1857. const LLAgentAccess& agent_access = gAgent.getAgentAccess();
  1858. // if the region is PG, we're happy already, so do nothing
  1859. // but if we're set to avoid either mature or adult, get us outta here
  1860. if ((sim_access == SIM_ACCESS_MATURE) &&
  1861. !agent_access.canAccessMature())
  1862. {
  1863. return false;
  1864. }
  1865. else if ((sim_access == SIM_ACCESS_ADULT) &&
  1866.  !agent_access.canAccessAdult())
  1867. {
  1868. return false;
  1869. }
  1870. }
  1871. bool isForSale = parcel->getForSale()
  1872. && ((parcel->getSalePrice() > 0) || (authorizeBuyer.notNull()));
  1873. bool isEmpowered
  1874. = forGroup ? gAgent.hasPowerInActiveGroup(GP_LAND_DEED) == TRUE : true;
  1875. bool isOwner
  1876. = parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID());
  1877. bool isAuthorized
  1878. = (authorizeBuyer.isNull() || (gAgent.getID() == authorizeBuyer));
  1879. return isForSale && !isOwner && isAuthorized  && isEmpowered;
  1880. }
  1881. void LLViewerParcelMgr::startBuyLand(BOOL is_for_group)
  1882. {
  1883. LLFloaterBuyLand::buyLand(getSelectionRegion(), mCurrentParcelSelection, is_for_group == TRUE);
  1884. }
  1885. void LLViewerParcelMgr::startSellLand()
  1886. {
  1887. LLFloaterSellLand::sellLand(getSelectionRegion(), mCurrentParcelSelection);
  1888. }
  1889. void LLViewerParcelMgr::startDivideLand()
  1890. {
  1891. if (!mSelected)
  1892. {
  1893. LLNotificationsUtil::add("CannotDivideLandNothingSelected");
  1894. return;
  1895. }
  1896. if (mCurrentParcelSelection->mWholeParcelSelected)
  1897. {
  1898. LLNotificationsUtil::add("CannotDivideLandPartialSelection");
  1899. return;
  1900. }
  1901. LLSD payload;
  1902. payload["west_south_border"] = ll_sd_from_vector3d(mWestSouth);
  1903. payload["east_north_border"] = ll_sd_from_vector3d(mEastNorth);
  1904. LLNotificationsUtil::add("LandDivideWarning", LLSD(), payload, callbackDivideLand);
  1905. }
  1906. // static
  1907. bool LLViewerParcelMgr::callbackDivideLand(const LLSD& notification, const LLSD& response)
  1908. {
  1909. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1910. LLVector3d west_south_d = ll_vector3d_from_sd(notification["payload"]["west_south_border"]);
  1911. LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]);
  1912. LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0;
  1913. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
  1914. if (!region)
  1915. {
  1916. LLNotificationsUtil::add("CannotDivideLandNoRegion");
  1917. return false;
  1918. }
  1919. if (0 == option)
  1920. {
  1921. LLVector3 west_south = region->getPosRegionFromGlobal(west_south_d);
  1922. LLVector3 east_north = region->getPosRegionFromGlobal(east_north_d);
  1923. LLMessageSystem* msg = gMessageSystem;
  1924. msg->newMessage("ParcelDivide");
  1925. msg->nextBlock("AgentData");
  1926. msg->addUUID("AgentID", gAgent.getID());
  1927. msg->addUUID("SessionID", gAgent.getSessionID());
  1928. msg->nextBlock("ParcelData");
  1929. msg->addF32("West", west_south.mV[VX]);
  1930. msg->addF32("South", west_south.mV[VY]);
  1931. msg->addF32("East", east_north.mV[VX]);
  1932. msg->addF32("North", east_north.mV[VY]);
  1933. msg->sendReliable(region->getHost());
  1934. }
  1935. return false;
  1936. }
  1937. void LLViewerParcelMgr::startJoinLand()
  1938. {
  1939. if (!mSelected)
  1940. {
  1941. LLNotificationsUtil::add("CannotJoinLandNothingSelected");
  1942. return;
  1943. }
  1944. if (mCurrentParcelSelection->mWholeParcelSelected)
  1945. {
  1946. LLNotificationsUtil::add("CannotJoinLandEntireParcelSelected");
  1947. return;
  1948. }
  1949. if (!mCurrentParcelSelection->mSelectedMultipleOwners)
  1950. {
  1951. LLNotificationsUtil::add("CannotJoinLandSelection");
  1952. return;
  1953. }
  1954. LLSD payload;
  1955. payload["west_south_border"] = ll_sd_from_vector3d(mWestSouth);
  1956. payload["east_north_border"] = ll_sd_from_vector3d(mEastNorth);
  1957. LLNotificationsUtil::add("JoinLandWarning", LLSD(), payload, callbackJoinLand);
  1958. }
  1959. // static
  1960. bool LLViewerParcelMgr::callbackJoinLand(const LLSD& notification, const LLSD& response)
  1961. {
  1962. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  1963. LLVector3d west_south_d = ll_vector3d_from_sd(notification["payload"]["west_south_border"]);
  1964. LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]);
  1965. LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0;
  1966. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
  1967. if (!region)
  1968. {
  1969. LLNotificationsUtil::add("CannotJoinLandNoRegion");
  1970. return false;
  1971. }
  1972. if (0 == option)
  1973. {
  1974. LLVector3 west_south = region->getPosRegionFromGlobal(west_south_d);
  1975. LLVector3 east_north = region->getPosRegionFromGlobal(east_north_d);
  1976. LLMessageSystem* msg = gMessageSystem;
  1977. msg->newMessage("ParcelJoin");
  1978. msg->nextBlock("AgentData");
  1979. msg->addUUID("AgentID", gAgent.getID());
  1980. msg->addUUID("SessionID", gAgent.getSessionID());
  1981. msg->nextBlock("ParcelData");
  1982. msg->addF32("West", west_south.mV[VX]);
  1983. msg->addF32("South", west_south.mV[VY]);
  1984. msg->addF32("East", east_north.mV[VX]);
  1985. msg->addF32("North", east_north.mV[VY]);
  1986. msg->sendReliable(region->getHost());
  1987. }
  1988. return false;
  1989. }
  1990. void LLViewerParcelMgr::startDeedLandToGroup()
  1991. {
  1992. if (!mSelected || !mCurrentParcel)
  1993. {
  1994. LLNotificationsUtil::add("CannotDeedLandNothingSelected");
  1995. return;
  1996. }
  1997. if (mRequestResult == PARCEL_RESULT_NO_DATA)
  1998. {
  1999. LLNotificationsUtil::add("CannotDeedLandWaitingForServer");
  2000. return;
  2001. }
  2002. if (mRequestResult == PARCEL_RESULT_MULTIPLE)
  2003. {
  2004. LLNotificationsUtil::add("CannotDeedLandMultipleSelected");
  2005. return;
  2006. }
  2007. LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
  2008. LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
  2009. if (!region)
  2010. {
  2011. LLNotificationsUtil::add("CannotDeedLandNoRegion");
  2012. return;
  2013. }
  2014. /*
  2015. if(!gAgent.isGodlike())
  2016. {
  2017. if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
  2018. && (mCurrentParcel->getOwnerID() != region->getOwner()))
  2019. {
  2020. LLSD args;
  2021. args["REGION"] = region->getName();
  2022. LLNotificationsUtil::add("CannotDeedLandNoTransfer", args);
  2023. return;
  2024. }
  2025. }
  2026. */
  2027. deedLandToGroup();
  2028. }
  2029. void LLViewerParcelMgr::reclaimParcel()
  2030. {
  2031. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
  2032. LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
  2033. if(parcel && parcel->getOwnerID().notNull()
  2034.    && (parcel->getOwnerID() != gAgent.getID())
  2035.    && regionp && (regionp->getOwner() == gAgent.getID()))
  2036. {
  2037. LLMessageSystem* msg = gMessageSystem;
  2038. msg->newMessage("ParcelReclaim");
  2039. msg->nextBlock("AgentData");
  2040. msg->addUUID("AgentID", gAgent.getID());
  2041. msg->addUUID("SessionID", gAgent.getSessionID());
  2042. msg->nextBlock("Data");
  2043. msg->addS32("LocalID", parcel->getLocalID());
  2044. msg->sendReliable(regionp->getHost());
  2045. }
  2046. }
  2047. // static
  2048. bool LLViewerParcelMgr::releaseAlertCB(const LLSD& notification, const LLSD& response)
  2049. {
  2050. S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
  2051. if (option == 0)
  2052. {
  2053. // Send the release message, not a force
  2054. LLViewerParcelMgr::getInstance()->sendParcelRelease();
  2055. }
  2056. return false;
  2057. }
  2058. void LLViewerParcelMgr::buyPass()
  2059. {
  2060. LLParcel* parcel = getParcelSelection()->getParcel();
  2061. if (!parcel) return;
  2062. LLViewerRegion* region = getSelectionRegion();
  2063. if (!region) return;
  2064. LLMessageSystem* msg = gMessageSystem;
  2065. msg->newMessageFast(_PREHASH_ParcelBuyPass);
  2066. msg->nextBlock("AgentData");
  2067. msg->addUUID("AgentID", gAgent.getID());
  2068. msg->addUUID("SessionID", gAgent.getSessionID());
  2069. msg->nextBlockFast(_PREHASH_ParcelData);
  2070. msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
  2071. msg->sendReliable( region->getHost() );
  2072. }
  2073. //Tells whether we are allowed to buy a pass or not
  2074. BOOL LLViewerParcelMgr::isCollisionBanned()
  2075. if ((mCollisionBanned == BA_ALLOWED) || (mCollisionBanned == BA_NOT_ON_LIST) || (mCollisionBanned == BA_NOT_IN_GROUP))
  2076. return FALSE;
  2077. else 
  2078. return TRUE;
  2079. }
  2080. // This implementation should mirror LLSimParcelMgr::isParcelOwnedBy
  2081. // static
  2082. BOOL LLViewerParcelMgr::isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power)
  2083. {
  2084. if (!parcelp)
  2085. {
  2086. return FALSE;
  2087. }
  2088. // Gods can always assume ownership.
  2089. if (gAgent.isGodlike())
  2090. {
  2091. return TRUE;
  2092. }
  2093. // The owner of a parcel automatically gets all powersr.
  2094. if (parcelp->getOwnerID() == gAgent.getID())
  2095. {
  2096. return TRUE;
  2097. }
  2098. // Only gods can assume 'ownership' of public land.
  2099. if (parcelp->isPublic())
  2100. {
  2101. return FALSE;
  2102. }
  2103. // Return whether or not the agent has group_proxy_power powers in the
  2104. // parcel's group.
  2105. return gAgent.hasPowerInGroup(parcelp->getOwnerID(), group_proxy_power);
  2106. }
  2107. // This implementation should mirror llSimParcelMgr::isParcelModifiableBy
  2108. // static
  2109. BOOL LLViewerParcelMgr::isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power)
  2110. {
  2111. // If the agent can assume ownership, it is probably modifiable.
  2112. BOOL rv = FALSE;
  2113. if (parcelp)
  2114. {
  2115. // *NOTE: This should only work for leased parcels, but group owned
  2116. // parcels cannot be OS_LEASED yet. Phoenix 2003-12-15.
  2117. rv = isParcelOwnedByAgent(parcelp, group_proxy_power);
  2118. // ... except for the case that the parcel is not OS_LEASED for agent-owned parcels.
  2119. if( (gAgent.getID() == parcelp->getOwnerID())
  2120. && !gAgent.isGodlike()
  2121. && (parcelp->getOwnershipStatus() != LLParcel::OS_LEASED) )
  2122. {
  2123. rv = FALSE;
  2124. }
  2125. }
  2126. return rv;
  2127. }
  2128. void sanitize_corners(const LLVector3d &corner1,
  2129. const LLVector3d &corner2,
  2130. LLVector3d &west_south_bottom,
  2131. LLVector3d &east_north_top)
  2132. {
  2133. west_south_bottom.mdV[VX] = llmin( corner1.mdV[VX], corner2.mdV[VX] );
  2134. west_south_bottom.mdV[VY] = llmin( corner1.mdV[VY], corner2.mdV[VY] );
  2135. west_south_bottom.mdV[VZ] = llmin( corner1.mdV[VZ], corner2.mdV[VZ] );
  2136. east_north_top.mdV[VX] = llmax( corner1.mdV[VX], corner2.mdV[VX] );
  2137. east_north_top.mdV[VY] = llmax( corner1.mdV[VY], corner2.mdV[VY] );
  2138. east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] );
  2139. }
  2140. void LLViewerParcelMgr::cleanupGlobals()
  2141. {
  2142. LLParcelSelection::sNullSelection = NULL;
  2143. }
  2144. LLViewerTexture* LLViewerParcelMgr::getBlockedImage() const
  2145. {
  2146. return sBlockedImage;
  2147. }
  2148. LLViewerTexture* LLViewerParcelMgr::getPassImage() const
  2149. {
  2150. return sPassImage;
  2151. }
  2152. boost::signals2::connection LLViewerParcelMgr::addAgentParcelChangedCallback(parcel_changed_callback_t cb)
  2153. {
  2154. return mAgentParcelChangedSignal.connect(cb);
  2155. }
  2156. /*
  2157.  * Set finish teleport callback. You can use it to observe all  teleport events.
  2158.  * NOTE:
  2159.  * After local( in one region) teleports we
  2160.  *  cannot rely on gAgent.getPositionGlobal(),
  2161.  *  so the new position gets passed explicitly.
  2162.  *  Use args of this callback to get global position of avatar after teleport event.
  2163.  */
  2164. boost::signals2::connection LLViewerParcelMgr::setTeleportFinishedCallback(teleport_finished_callback_t cb)
  2165. {
  2166. return mTeleportFinishedSignal.connect(cb);
  2167. }
  2168. boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(parcel_changed_callback_t cb)
  2169. {
  2170. return mTeleportFailedSignal.connect(cb);
  2171. }
  2172. /* Ok, we're notified that teleport has been finished.
  2173.  * We should now propagate the notification via mTeleportFinishedSignal
  2174.  * to all interested parties.
  2175.  */
  2176. void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos)
  2177. {
  2178. // Treat only teleports within the same parcel as local (EXT-3139).
  2179. if (local && LLViewerParcelMgr::getInstance()->inAgentParcel(new_pos))
  2180. {
  2181. // Local teleport. We already have the agent parcel data.
  2182. // Emit the signal immediately.
  2183. getInstance()->mTeleportFinishedSignal(new_pos);
  2184. }
  2185. else
  2186. {
  2187. // Non-local teleport (inter-region or between different parcels of the same region).
  2188. // The agent parcel data has not been updated yet.
  2189. // Let's wait for the update and then emit the signal.
  2190. mTeleportInProgress = TRUE;
  2191. }
  2192. }
  2193. void LLViewerParcelMgr::onTeleportFailed()
  2194. {
  2195. mTeleportFailedSignal();
  2196. }