PageRenderTime 68ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/OpenMetaverse/Modules/ParcelManager.cs

https://bitbucket.org/VirtualReality/3rdparty-addon-modules
C# | 2280 lines | 1293 code | 246 blank | 741 comment | 111 complexity | ade307e822a96a4cedda2b1a4e5d7e63 MD5 | raw file
  1. /*
  2. * Copyright (c) 2007-2009, openmetaverse.org
  3. * All rights reserved.
  4. *
  5. * - Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * - Neither the name of the openmetaverse.org nor the names
  11. * of its contributors may be used to endorse or promote products derived from
  12. * this software without specific prior written permission.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. * POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. using System;
  27. using System.Threading;
  28. using System.Reflection;
  29. using System.Collections.Generic;
  30. using OpenMetaverse.Http;
  31. using OpenMetaverse.Packets;
  32. using OpenMetaverse.Interfaces;
  33. using OpenMetaverse.StructuredData;
  34. using OpenMetaverse.Messages.Linden;
  35. namespace OpenMetaverse
  36. {
  37. #region Enums
  38. /// <summary>
  39. /// Type of return to use when returning objects from a parcel
  40. /// </summary>
  41. public enum ObjectReturnType : uint
  42. {
  43. /// <summary></summary>
  44. None = 0,
  45. /// <summary>Return objects owned by parcel owner</summary>
  46. Owner = 1 << 1,
  47. /// <summary>Return objects set to group</summary>
  48. Group = 1 << 2,
  49. /// <summary>Return objects not owned by parcel owner or set to group</summary>
  50. Other = 1 << 3,
  51. /// <summary>Return a specific list of objects on parcel</summary>
  52. List = 1 << 4,
  53. /// <summary>Return objects that are marked for-sale</summary>
  54. Sell = 1 << 5
  55. }
  56. /// <summary>
  57. /// Blacklist/Whitelist flags used in parcels Access List
  58. /// </summary>
  59. public enum ParcelAccessFlags : uint
  60. {
  61. /// <summary>Agent is denied access</summary>
  62. NoAccess = 0,
  63. /// <summary>Agent is granted access</summary>
  64. Access = 1
  65. }
  66. /// <summary>
  67. /// The result of a request for parcel properties
  68. /// </summary>
  69. public enum ParcelResult : int
  70. {
  71. /// <summary>No matches were found for the request</summary>
  72. NoData = -1,
  73. /// <summary>Request matched a single parcel</summary>
  74. Single = 0,
  75. /// <summary>Request matched multiple parcels</summary>
  76. Multiple = 1
  77. }
  78. /// <summary>
  79. /// Flags used in the ParcelAccessListRequest packet to specify whether
  80. /// we want the access list (whitelist), ban list (blacklist), or both
  81. /// </summary>
  82. [Flags]
  83. public enum AccessList : uint
  84. {
  85. /// <summary>Request the access list</summary>
  86. Access = 1 << 0,
  87. /// <summary>Request the ban list</summary>
  88. Ban = 1 << 1,
  89. /// <summary>Request both White and Black lists</summary>
  90. Both = Access | Ban
  91. }
  92. /// <summary>
  93. /// Sequence ID in ParcelPropertiesReply packets (sent when avatar
  94. /// tries to cross a parcel border)
  95. /// </summary>
  96. public enum ParcelPropertiesStatus : int
  97. {
  98. /// <summary>Parcel is currently selected</summary>
  99. ParcelSelected = -10000,
  100. /// <summary>Parcel restricted to a group the avatar is not a
  101. /// member of</summary>
  102. CollisionNotInGroup = -20000,
  103. /// <summary>Avatar is banned from the parcel</summary>
  104. CollisionBanned = -30000,
  105. /// <summary>Parcel is restricted to an access list that the
  106. /// avatar is not on</summary>
  107. CollisionNotOnAccessList = -40000,
  108. /// <summary>Response to hovering over a parcel</summary>
  109. HoveredOverParcel = -50000
  110. }
  111. /// <summary>
  112. /// The tool to use when modifying terrain levels
  113. /// </summary>
  114. public enum TerraformAction : byte
  115. {
  116. /// <summary>Level the terrain</summary>
  117. Level = 0,
  118. /// <summary>Raise the terrain</summary>
  119. Raise = 1,
  120. /// <summary>Lower the terrain</summary>
  121. Lower = 2,
  122. /// <summary>Smooth the terrain</summary>
  123. Smooth = 3,
  124. /// <summary>Add random noise to the terrain</summary>
  125. Noise = 4,
  126. /// <summary>Revert terrain to simulator default</summary>
  127. Revert = 5
  128. }
  129. /// <summary>
  130. /// The tool size to use when changing terrain levels
  131. /// </summary>
  132. public enum TerraformBrushSize : byte
  133. {
  134. /// <summary>Small</summary>
  135. Small = 1,
  136. /// <summary>Medium</summary>
  137. Medium = 2,
  138. /// <summary>Large</summary>
  139. Large = 4
  140. }
  141. /// <summary>
  142. /// Reasons agent is denied access to a parcel on the simulator
  143. /// </summary>
  144. public enum AccessDeniedReason : byte
  145. {
  146. /// <summary>Agent is not denied, access is granted</summary>
  147. NotDenied = 0,
  148. /// <summary>Agent is not a member of the group set for the parcel, or which owns the parcel</summary>
  149. NotInGroup = 1,
  150. /// <summary>Agent is not on the parcels specific allow list</summary>
  151. NotOnAllowList = 2,
  152. /// <summary>Agent is on the parcels ban list</summary>
  153. BannedFromParcel = 3,
  154. /// <summary>Unknown</summary>
  155. NoAccess = 4,
  156. /// <summary>Agent is not age verified and parcel settings deny access to non age verified avatars</summary>
  157. NotAgeVerified = 5
  158. }
  159. /// <summary>
  160. /// Parcel overlay type. This is used primarily for highlighting and
  161. /// coloring which is why it is a single integer instead of a set of
  162. /// flags
  163. /// </summary>
  164. /// <remarks>These values seem to be poorly thought out. The first three
  165. /// bits represent a single value, not flags. For example Auction (0x05) is
  166. /// not a combination of OwnedByOther (0x01) and ForSale(0x04). However,
  167. /// the BorderWest and BorderSouth values are bit flags that get attached
  168. /// to the value stored in the first three bits. Bits four, five, and six
  169. /// are unused</remarks>
  170. [Flags]
  171. public enum ParcelOverlayType : byte
  172. {
  173. /// <summary>Public land</summary>
  174. Public = 0,
  175. /// <summary>Land is owned by another avatar</summary>
  176. OwnedByOther = 1,
  177. /// <summary>Land is owned by a group</summary>
  178. OwnedByGroup = 2,
  179. /// <summary>Land is owned by the current avatar</summary>
  180. OwnedBySelf = 3,
  181. /// <summary>Land is for sale</summary>
  182. ForSale = 4,
  183. /// <summary>Land is being auctioned</summary>
  184. Auction = 5,
  185. /// <summary>Land is private</summary>
  186. Private = 32,
  187. /// <summary>To the west of this area is a parcel border</summary>
  188. BorderWest = 64,
  189. /// <summary>To the south of this area is a parcel border</summary>
  190. BorderSouth = 128
  191. }
  192. /// <summary>
  193. /// Various parcel properties
  194. /// </summary>
  195. [Flags]
  196. public enum ParcelFlags : uint
  197. {
  198. /// <summary>No flags set</summary>
  199. None = 0,
  200. /// <summary>Allow avatars to fly (a client-side only restriction)</summary>
  201. AllowFly = 1 << 0,
  202. /// <summary>Allow foreign scripts to run</summary>
  203. AllowOtherScripts = 1 << 1,
  204. /// <summary>This parcel is for sale</summary>
  205. ForSale = 1 << 2,
  206. /// <summary>Allow avatars to create a landmark on this parcel</summary>
  207. AllowLandmark = 1 << 3,
  208. /// <summary>Allows all avatars to edit the terrain on this parcel</summary>
  209. AllowTerraform = 1 << 4,
  210. /// <summary>Avatars have health and can take damage on this parcel.
  211. /// If set, avatars can be killed and sent home here</summary>
  212. AllowDamage = 1 << 5,
  213. /// <summary>Foreign avatars can create objects here</summary>
  214. CreateObjects = 1 << 6,
  215. /// <summary>All objects on this parcel can be purchased</summary>
  216. ForSaleObjects = 1 << 7,
  217. /// <summary>Access is restricted to a group</summary>
  218. UseAccessGroup = 1 << 8,
  219. /// <summary>Access is restricted to a whitelist</summary>
  220. UseAccessList = 1 << 9,
  221. /// <summary>Ban blacklist is enabled</summary>
  222. UseBanList = 1 << 10,
  223. /// <summary>Unknown</summary>
  224. UsePassList = 1 << 11,
  225. /// <summary>List this parcel in the search directory</summary>
  226. ShowDirectory = 1 << 12,
  227. /// <summary>Allow personally owned parcels to be deeded to group</summary>
  228. AllowDeedToGroup = 1 << 13,
  229. /// <summary>If Deeded, owner contributes required tier to group parcel is deeded to</summary>
  230. ContributeWithDeed = 1 << 14,
  231. /// <summary>Restrict sounds originating on this parcel to the
  232. /// parcel boundaries</summary>
  233. SoundLocal = 1 << 15,
  234. /// <summary>Objects on this parcel are sold when the land is
  235. /// purchsaed</summary>
  236. SellParcelObjects = 1 << 16,
  237. /// <summary>Allow this parcel to be published on the web</summary>
  238. AllowPublish = 1 << 17,
  239. /// <summary>The information for this parcel is mature content</summary>
  240. MaturePublish = 1 << 18,
  241. /// <summary>The media URL is an HTML page</summary>
  242. UrlWebPage = 1 << 19,
  243. /// <summary>The media URL is a raw HTML string</summary>
  244. UrlRawHtml = 1 << 20,
  245. /// <summary>Restrict foreign object pushes</summary>
  246. RestrictPushObject = 1 << 21,
  247. /// <summary>Ban all non identified/transacted avatars</summary>
  248. DenyAnonymous = 1 << 22,
  249. // <summary>Ban all identified avatars [OBSOLETE]</summary>
  250. //[Obsolete]
  251. // This was obsoleted in 1.19.0 but appears to be recycled and is used on linden homes parcels
  252. LindenHome = 1 << 23,
  253. // <summary>Ban all transacted avatars [OBSOLETE]</summary>
  254. //[Obsolete]
  255. //DenyTransacted = 1 << 24,
  256. /// <summary>Allow group-owned scripts to run</summary>
  257. AllowGroupScripts = 1 << 25,
  258. /// <summary>Allow object creation by group members or group
  259. /// objects</summary>
  260. CreateGroupObjects = 1 << 26,
  261. /// <summary>Allow all objects to enter this parcel</summary>
  262. AllowAPrimitiveEntry = 1 << 27,
  263. /// <summary>Only allow group and owner objects to enter this parcel</summary>
  264. AllowGroupObjectEntry = 1 << 28,
  265. /// <summary>Voice Enabled on this parcel</summary>
  266. AllowVoiceChat = 1 << 29,
  267. /// <summary>Use Estate Voice channel for Voice on this parcel</summary>
  268. UseEstateVoiceChan = 1 << 30,
  269. /// <summary>Deny Age Unverified Users</summary>
  270. DenyAgeUnverified = 1U << 31
  271. }
  272. /// <summary>
  273. /// Parcel ownership status
  274. /// </summary>
  275. public enum ParcelStatus : sbyte
  276. {
  277. /// <summary>Placeholder</summary>
  278. None = -1,
  279. /// <summary>Parcel is leased (owned) by an avatar or group</summary>
  280. Leased = 0,
  281. /// <summary>Parcel is in process of being leased (purchased) by an avatar or group</summary>
  282. LeasePending = 1,
  283. /// <summary>Parcel has been abandoned back to Governor Linden</summary>
  284. Abandoned = 2
  285. }
  286. /// <summary>
  287. /// Category parcel is listed in under search
  288. /// </summary>
  289. public enum ParcelCategory : sbyte
  290. {
  291. /// <summary>No assigned category</summary>
  292. None = 0,
  293. /// <summary>Linden Infohub or public area</summary>
  294. Linden,
  295. /// <summary>Adult themed area</summary>
  296. Adult,
  297. /// <summary>Arts and Culture</summary>
  298. Arts,
  299. /// <summary>Business</summary>
  300. Business,
  301. /// <summary>Educational</summary>
  302. Educational,
  303. /// <summary>Gaming</summary>
  304. Gaming,
  305. /// <summary>Hangout or Club</summary>
  306. Hangout,
  307. /// <summary>Newcomer friendly</summary>
  308. Newcomer,
  309. /// <summary>Parks and Nature</summary>
  310. Park,
  311. /// <summary>Residential</summary>
  312. Residential,
  313. /// <summary>Shopping</summary>
  314. Shopping,
  315. /// <summary>Not Used?</summary>
  316. Stage,
  317. /// <summary>Other</summary>
  318. Other,
  319. /// <summary>Not an actual category, only used for queries</summary>
  320. Any = -1
  321. }
  322. /// <summary>
  323. /// Type of teleport landing for a parcel
  324. /// </summary>
  325. public enum LandingType : byte
  326. {
  327. /// <summary>Unset, simulator default</summary>
  328. None = 0,
  329. /// <summary>Specific landing point set for this parcel</summary>
  330. LandingPoint = 1,
  331. /// <summary>No landing point set, direct teleports enabled for
  332. /// this parcel</summary>
  333. Direct = 2
  334. }
  335. /// <summary>
  336. /// Parcel Media Command used in ParcelMediaCommandMessage
  337. /// </summary>
  338. public enum ParcelMediaCommand : uint
  339. {
  340. /// <summary>Stop the media stream and go back to the first frame</summary>
  341. Stop = 0,
  342. /// <summary>Pause the media stream (stop playing but stay on current frame)</summary>
  343. Pause,
  344. /// <summary>Start the current media stream playing and stop when the end is reached</summary>
  345. Play,
  346. /// <summary>Start the current media stream playing,
  347. /// loop to the beginning when the end is reached and continue to play</summary>
  348. Loop,
  349. /// <summary>Specifies the texture to replace with video</summary>
  350. /// <remarks>If passing the key of a texture, it must be explicitly typecast as a key,
  351. /// not just passed within double quotes.</remarks>
  352. Texture,
  353. /// <summary>Specifies the movie URL (254 characters max)</summary>
  354. URL,
  355. /// <summary>Specifies the time index at which to begin playing</summary>
  356. Time,
  357. /// <summary>Specifies a single agent to apply the media command to</summary>
  358. Agent,
  359. /// <summary>Unloads the stream. While the stop command sets the texture to the first frame of the movie,
  360. /// unload resets it to the real texture that the movie was replacing.</summary>
  361. Unload,
  362. /// <summary>Turn on/off the auto align feature, similar to the auto align checkbox in the parcel media properties
  363. /// (NOT to be confused with the "align" function in the textures view of the editor!) Takes TRUE or FALSE as parameter.</summary>
  364. AutoAlign,
  365. /// <summary>Allows a Web page or image to be placed on a prim (1.19.1 RC0 and later only).
  366. /// Use "text/html" for HTML.</summary>
  367. Type,
  368. /// <summary>Resizes a Web page to fit on x, y pixels (1.19.1 RC0 and later only).</summary>
  369. /// <remarks>This might still not be working</remarks>
  370. Size,
  371. /// <summary>Sets a description for the media being displayed (1.19.1 RC0 and later only).</summary>
  372. Desc
  373. }
  374. #endregion Enums
  375. #region Structs
  376. /// <summary>
  377. /// Some information about a parcel of land returned from a DirectoryManager search
  378. /// </summary>
  379. public struct ParcelInfo
  380. {
  381. /// <summary>Global Key of record</summary>
  382. public UUID ID;
  383. /// <summary>Parcel Owners <seealso cref="UUID"/></summary>
  384. public UUID OwnerID;
  385. /// <summary>Name field of parcel, limited to 128 characters</summary>
  386. public string Name;
  387. /// <summary>Description field of parcel, limited to 256 characters</summary>
  388. public string Description;
  389. /// <summary>Total Square meters of parcel</summary>
  390. public int ActualArea;
  391. /// <summary>Total area billable as Tier, for group owned land this will be 10% less than ActualArea</summary>
  392. public int BillableArea;
  393. /// <summary>True of parcel is in Mature simulator</summary>
  394. public bool Mature;
  395. /// <summary>Grid global X position of parcel</summary>
  396. public float GlobalX;
  397. /// <summary>Grid global Y position of parcel</summary>
  398. public float GlobalY;
  399. /// <summary>Grid global Z position of parcel (not used)</summary>
  400. public float GlobalZ;
  401. /// <summary>Name of simulator parcel is located in</summary>
  402. public string SimName;
  403. /// <summary>Texture <seealso cref="T:OpenMetaverse.UUID"/> of parcels display picture</summary>
  404. public UUID SnapshotID;
  405. /// <summary>Float representing calculated traffic based on time spent on parcel by avatars</summary>
  406. public float Dwell;
  407. /// <summary>Sale price of parcel (not used)</summary>
  408. public int SalePrice;
  409. /// <summary>Auction ID of parcel</summary>
  410. public int AuctionID;
  411. }
  412. /// <summary>
  413. /// Parcel Media Information
  414. /// </summary>
  415. public struct ParcelMedia
  416. {
  417. /// <summary>A byte, if 0x1 viewer should auto scale media to fit object</summary>
  418. public bool MediaAutoScale;
  419. /// <summary>A boolean, if true the viewer should loop the media</summary>
  420. public bool MediaLoop;
  421. /// <summary>The Asset UUID of the Texture which when applied to a
  422. /// primitive will display the media</summary>
  423. public UUID MediaID;
  424. /// <summary>A URL which points to any Quicktime supported media type</summary>
  425. public string MediaURL;
  426. /// <summary>A description of the media</summary>
  427. public string MediaDesc;
  428. /// <summary>An Integer which represents the height of the media</summary>
  429. public int MediaHeight;
  430. /// <summary>An integer which represents the width of the media</summary>
  431. public int MediaWidth;
  432. /// <summary>A string which contains the mime type of the media</summary>
  433. public string MediaType;
  434. }
  435. #endregion Structs
  436. #region Parcel Class
  437. /// <summary>
  438. /// Parcel of land, a portion of virtual real estate in a simulator
  439. /// </summary>
  440. public class Parcel
  441. {
  442. /// <summary>The total number of contiguous 4x4 meter blocks your agent owns within this parcel</summary>
  443. public int SelfCount;
  444. /// <summary>The total number of contiguous 4x4 meter blocks contained in this parcel owned by a group or agent other than your own</summary>
  445. public int OtherCount;
  446. /// <summary>Deprecated, Value appears to always be 0</summary>
  447. public int PublicCount;
  448. /// <summary>Simulator-local ID of this parcel</summary>
  449. public int LocalID;
  450. /// <summary>UUID of the owner of this parcel</summary>
  451. public UUID OwnerID;
  452. /// <summary>Whether the land is deeded to a group or not</summary>
  453. public bool IsGroupOwned;
  454. /// <summary></summary>
  455. public uint AuctionID;
  456. /// <summary>Date land was claimed</summary>
  457. public DateTime ClaimDate;
  458. /// <summary>Appears to always be zero</summary>
  459. public int ClaimPrice;
  460. /// <summary>This field is no longer used</summary>
  461. public int RentPrice;
  462. /// <summary>Minimum corner of the axis-aligned bounding box for this
  463. /// parcel</summary>
  464. public Vector3 AABBMin;
  465. /// <summary>Maximum corner of the axis-aligned bounding box for this
  466. /// parcel</summary>
  467. public Vector3 AABBMax;
  468. /// <summary>Bitmap describing land layout in 4x4m squares across the
  469. /// entire region</summary>
  470. public byte[] Bitmap;
  471. /// <summary>Total parcel land area</summary>
  472. public int Area;
  473. /// <summary></summary>
  474. public ParcelStatus Status;
  475. /// <summary>Maximum primitives across the entire simulator owned by the same agent or group that owns this parcel that can be used</summary>
  476. public int SimWideMaxPrims;
  477. /// <summary>Total primitives across the entire simulator calculated by combining the allowed prim counts for each parcel
  478. /// owned by the agent or group that owns this parcel</summary>
  479. public int SimWideTotalPrims;
  480. /// <summary>Maximum number of primitives this parcel supports</summary>
  481. public int MaxPrims;
  482. /// <summary>Total number of primitives on this parcel</summary>
  483. public int TotalPrims;
  484. /// <summary>For group-owned parcels this indicates the total number of prims deeded to the group,
  485. /// for parcels owned by an individual this inicates the number of prims owned by the individual</summary>
  486. public int OwnerPrims;
  487. /// <summary>Total number of primitives owned by the parcel group on
  488. /// this parcel, or for parcels owned by an individual with a group set the
  489. /// total number of prims set to that group.</summary>
  490. public int GroupPrims;
  491. /// <summary>Total number of prims owned by other avatars that are not set to group, or not the parcel owner</summary>
  492. public int OtherPrims;
  493. /// <summary>A bonus multiplier which allows parcel prim counts to go over times this amount, this does not affect
  494. /// the max prims per simulator. e.g: 117 prim parcel limit x 1.5 bonus = 175 allowed</summary>
  495. public float ParcelPrimBonus;
  496. /// <summary>Autoreturn value in minutes for others' objects</summary>
  497. public int OtherCleanTime;
  498. /// <summary></summary>
  499. public ParcelFlags Flags;
  500. /// <summary>Sale price of the parcel, only useful if ForSale is set</summary>
  501. /// <remarks>The SalePrice will remain the same after an ownership
  502. /// transfer (sale), so it can be used to see the purchase price after
  503. /// a sale if the new owner has not changed it</remarks>
  504. public int SalePrice;
  505. /// <summary>Parcel Name</summary>
  506. public string Name;
  507. /// <summary>Parcel Description</summary>
  508. public string Desc;
  509. /// <summary>URL For Music Stream</summary>
  510. public string MusicURL;
  511. /// <summary></summary>
  512. public UUID GroupID;
  513. /// <summary>Price for a temporary pass</summary>
  514. public int PassPrice;
  515. /// <summary>How long is pass valid for</summary>
  516. public float PassHours;
  517. /// <summary></summary>
  518. public ParcelCategory Category;
  519. /// <summary>Key of authorized buyer</summary>
  520. public UUID AuthBuyerID;
  521. /// <summary>Key of parcel snapshot</summary>
  522. public UUID SnapshotID;
  523. /// <summary>The landing point location</summary>
  524. public Vector3 UserLocation;
  525. /// <summary>The landing point LookAt</summary>
  526. public Vector3 UserLookAt;
  527. /// <summary>The type of landing enforced from the <see cref="LandingType"/> enum</summary>
  528. public LandingType Landing;
  529. /// <summary></summary>
  530. public float Dwell;
  531. /// <summary></summary>
  532. public bool RegionDenyAnonymous;
  533. /// <summary></summary>
  534. public bool RegionPushOverride;
  535. /// <summary>Access list of who is whitelisted on this
  536. /// parcel</summary>
  537. public List<ParcelManager.ParcelAccessEntry> AccessWhiteList;
  538. /// <summary>Access list of who is blacklisted on this
  539. /// parcel</summary>
  540. public List<ParcelManager.ParcelAccessEntry> AccessBlackList;
  541. /// <summary>TRUE of region denies access to age unverified users</summary>
  542. public bool RegionDenyAgeUnverified;
  543. /// <summary>true to obscure (hide) media url</summary>
  544. public bool ObscureMedia;
  545. /// <summary>true to obscure (hide) music url</summary>
  546. public bool ObscureMusic;
  547. /// <summary>A struct containing media details</summary>
  548. public ParcelMedia Media;
  549. /// <summary>
  550. /// Displays a parcel object in string format
  551. /// </summary>
  552. /// <returns>string containing key=value pairs of a parcel object</returns>
  553. public override string ToString()
  554. {
  555. string result = "";
  556. Type parcelType = this.GetType();
  557. FieldInfo[] fields = parcelType.GetFields();
  558. foreach (FieldInfo field in fields)
  559. {
  560. result += (field.Name + " = " + field.GetValue(this) + " ");
  561. }
  562. return result;
  563. }
  564. /// <summary>
  565. /// Defalt constructor
  566. /// </summary>
  567. /// <param name="localID">Local ID of this parcel</param>
  568. public Parcel(int localID)
  569. {
  570. LocalID = localID;
  571. ClaimDate = Utils.Epoch;
  572. Bitmap = Utils.EmptyBytes;
  573. Name = String.Empty;
  574. Desc = String.Empty;
  575. MusicURL = String.Empty;
  576. AccessWhiteList = new List<ParcelManager.ParcelAccessEntry>(0);
  577. AccessBlackList = new List<ParcelManager.ParcelAccessEntry>(0);
  578. Media = new ParcelMedia();
  579. }
  580. /// <summary>
  581. /// Update the simulator with any local changes to this Parcel object
  582. /// </summary>
  583. /// <param name="simulator">Simulator to send updates to</param>
  584. /// <param name="wantReply">Whether we want the simulator to confirm
  585. /// the update with a reply packet or not</param>
  586. public void Update(Simulator simulator, bool wantReply)
  587. {
  588. Uri url = simulator.Caps.CapabilityURI("ParcelPropertiesUpdate");
  589. if (url != null)
  590. {
  591. ParcelPropertiesUpdateMessage req = new ParcelPropertiesUpdateMessage();
  592. req.AuthBuyerID = this.AuthBuyerID;
  593. req.Category = this.Category;
  594. req.Desc = this.Desc;
  595. req.GroupID = this.GroupID;
  596. req.Landing = this.Landing;
  597. req.LocalID = this.LocalID;
  598. req.MediaAutoScale = this.Media.MediaAutoScale;
  599. req.MediaDesc = this.Media.MediaDesc;
  600. req.MediaHeight = this.Media.MediaHeight;
  601. req.MediaID = this.Media.MediaID;
  602. req.MediaLoop = this.Media.MediaLoop;
  603. req.MediaType = this.Media.MediaType;
  604. req.MediaURL = this.Media.MediaURL;
  605. req.MediaWidth = this.Media.MediaWidth;
  606. req.MusicURL = this.MusicURL;
  607. req.Name = this.Name;
  608. req.ObscureMedia = this.ObscureMedia;
  609. req.ObscureMusic = this.ObscureMusic;
  610. req.ParcelFlags = this.Flags;
  611. req.PassHours = this.PassHours;
  612. req.PassPrice = (uint)this.PassPrice;
  613. req.SalePrice = (uint)this.SalePrice;
  614. req.SnapshotID = this.SnapshotID;
  615. req.UserLocation = this.UserLocation;
  616. req.UserLookAt = this.UserLookAt;
  617. OSDMap body = req.Serialize();
  618. CapsClient capsPost = new CapsClient(url);
  619. capsPost.BeginGetResponse(body, OSDFormat.Xml, simulator.Client.Settings.CAPS_TIMEOUT);
  620. }
  621. else
  622. {
  623. ParcelPropertiesUpdatePacket request = new ParcelPropertiesUpdatePacket();
  624. request.AgentData.AgentID = simulator.Client.Self.AgentID;
  625. request.AgentData.SessionID = simulator.Client.Self.SessionID;
  626. request.ParcelData.LocalID = this.LocalID;
  627. request.ParcelData.AuthBuyerID = this.AuthBuyerID;
  628. request.ParcelData.Category = (byte)this.Category;
  629. request.ParcelData.Desc = Utils.StringToBytes(this.Desc);
  630. request.ParcelData.GroupID = this.GroupID;
  631. request.ParcelData.LandingType = (byte)this.Landing;
  632. request.ParcelData.MediaAutoScale = (this.Media.MediaAutoScale) ? (byte)0x1 : (byte)0x0;
  633. request.ParcelData.MediaID = this.Media.MediaID;
  634. request.ParcelData.MediaURL = Utils.StringToBytes(this.Media.MediaURL.ToString());
  635. request.ParcelData.MusicURL = Utils.StringToBytes(this.MusicURL.ToString());
  636. request.ParcelData.Name = Utils.StringToBytes(this.Name);
  637. if (wantReply) request.ParcelData.Flags = 1;
  638. request.ParcelData.ParcelFlags = (uint)this.Flags;
  639. request.ParcelData.PassHours = this.PassHours;
  640. request.ParcelData.PassPrice = this.PassPrice;
  641. request.ParcelData.SalePrice = this.SalePrice;
  642. request.ParcelData.SnapshotID = this.SnapshotID;
  643. request.ParcelData.UserLocation = this.UserLocation;
  644. request.ParcelData.UserLookAt = this.UserLookAt;
  645. simulator.SendPacket(request);
  646. }
  647. UpdateOtherCleanTime(simulator);
  648. }
  649. /// <summary>
  650. /// Set Autoreturn time
  651. /// </summary>
  652. /// <param name="simulator">Simulator to send the update to</param>
  653. public void UpdateOtherCleanTime(Simulator simulator)
  654. {
  655. ParcelSetOtherCleanTimePacket request = new ParcelSetOtherCleanTimePacket();
  656. request.AgentData.AgentID = simulator.Client.Self.AgentID;
  657. request.AgentData.SessionID = simulator.Client.Self.SessionID;
  658. request.ParcelData.LocalID = this.LocalID;
  659. request.ParcelData.OtherCleanTime = this.OtherCleanTime;
  660. simulator.SendPacket(request);
  661. }
  662. }
  663. #endregion Parcel Class
  664. /// <summary>
  665. /// Parcel (subdivided simulator lots) subsystem
  666. /// </summary>
  667. public class ParcelManager
  668. {
  669. #region Structs
  670. /// <summary>
  671. /// Parcel Accesslist
  672. /// </summary>
  673. public struct ParcelAccessEntry
  674. {
  675. /// <summary>Agents <seealso cref="T:OpenMetaverse.UUID"/></summary>
  676. public UUID AgentID;
  677. /// <summary></summary>
  678. public DateTime Time;
  679. /// <summary>Flags for specific entry in white/black lists</summary>
  680. public AccessList Flags;
  681. }
  682. /// <summary>
  683. /// Owners of primitives on parcel
  684. /// </summary>
  685. public struct ParcelPrimOwners
  686. {
  687. /// <summary>Prim Owners <seealso cref="T:OpenMetaverse.UUID"/></summary>
  688. public UUID OwnerID;
  689. /// <summary>True of owner is group</summary>
  690. public bool IsGroupOwned;
  691. /// <summary>Total count of prims owned by OwnerID</summary>
  692. public int Count;
  693. /// <summary>true of OwnerID is currently online and is not a group</summary>
  694. public bool OnlineStatus;
  695. /// <summary>The date of the most recent prim left by OwnerID</summary>
  696. public DateTime NewestPrim;
  697. }
  698. #endregion Structs
  699. #region Delegates
  700. /// <summary>
  701. /// Called once parcel resource usage information has been collected
  702. /// </summary>
  703. /// <param name="success">Indicates if operation was successfull</param>
  704. /// <param name="info">Parcel resource usage information</param>
  705. public delegate void LandResourcesCallback(bool success, LandResourcesInfo info);
  706. /// <summary>The event subscribers. null if no subcribers</summary>
  707. private EventHandler<ParcelDwellReplyEventArgs> m_DwellReply;
  708. /// <summary>Raises the ParcelDwellReply event</summary>
  709. /// <param name="e">A ParcelDwellReplyEventArgs object containing the
  710. /// data returned from the simulator</param>
  711. protected virtual void OnParcelDwellReply(ParcelDwellReplyEventArgs e)
  712. {
  713. EventHandler<ParcelDwellReplyEventArgs> handler = m_DwellReply;
  714. if (handler != null)
  715. handler(this, e);
  716. }
  717. /// <summary>Thread sync lock object</summary>
  718. private readonly object m_DwellReplyLock = new object();
  719. /// <summary>Raised when the simulator responds to a <see cref="RequestDwell"/> request</summary>
  720. public event EventHandler<ParcelDwellReplyEventArgs> ParcelDwellReply
  721. {
  722. add { lock (m_DwellReplyLock) { m_DwellReply += value; } }
  723. remove { lock (m_DwellReplyLock) { m_DwellReply -= value; } }
  724. }
  725. /// <summary>The event subscribers. null if no subcribers</summary>
  726. private EventHandler<ParcelInfoReplyEventArgs> m_ParcelInfo;
  727. /// <summary>Raises the ParcelInfoReply event</summary>
  728. /// <param name="e">A ParcelInfoReplyEventArgs object containing the
  729. /// data returned from the simulator</param>
  730. protected virtual void OnParcelInfoReply(ParcelInfoReplyEventArgs e)
  731. {
  732. EventHandler<ParcelInfoReplyEventArgs> handler = m_ParcelInfo;
  733. if (handler != null)
  734. handler(this, e);
  735. }
  736. /// <summary>Thread sync lock object</summary>
  737. private readonly object m_ParcelInfoLock = new object();
  738. /// <summary>Raised when the simulator responds to a <see cref="RequestParcelInfo"/> request</summary>
  739. public event EventHandler<ParcelInfoReplyEventArgs> ParcelInfoReply
  740. {
  741. add { lock (m_ParcelInfoLock) { m_ParcelInfo += value; } }
  742. remove { lock (m_ParcelInfoLock) { m_ParcelInfo -= value; } }
  743. }
  744. /// <summary>The event subscribers. null if no subcribers</summary>
  745. private EventHandler<ParcelPropertiesEventArgs> m_ParcelProperties;
  746. /// <summary>Raises the ParcelProperties event</summary>
  747. /// <param name="e">A ParcelPropertiesEventArgs object containing the
  748. /// data returned from the simulator</param>
  749. protected virtual void OnParcelProperties(ParcelPropertiesEventArgs e)
  750. {
  751. EventHandler<ParcelPropertiesEventArgs> handler = m_ParcelProperties;
  752. if (handler != null)
  753. handler(this, e);
  754. }
  755. /// <summary>Thread sync lock object</summary>
  756. private readonly object m_ParcelPropertiesLock = new object();
  757. /// <summary>Raised when the simulator responds to a <see cref="RequestParcelProperties"/> request</summary>
  758. public event EventHandler<ParcelPropertiesEventArgs> ParcelProperties
  759. {
  760. add { lock (m_ParcelPropertiesLock) { m_ParcelProperties += value; } }
  761. remove { lock (m_ParcelPropertiesLock) { m_ParcelProperties -= value; } }
  762. }
  763. /// <summary>The event subscribers. null if no subcribers</summary>
  764. private EventHandler<ParcelAccessListReplyEventArgs> m_ParcelACL;
  765. /// <summary>Raises the ParcelAccessListReply event</summary>
  766. /// <param name="e">A ParcelAccessListReplyEventArgs object containing the
  767. /// data returned from the simulator</param>
  768. protected virtual void OnParcelAccessListReply(ParcelAccessListReplyEventArgs e)
  769. {
  770. EventHandler<ParcelAccessListReplyEventArgs> handler = m_ParcelACL;
  771. if (handler != null)
  772. handler(this, e);
  773. }
  774. /// <summary>Thread sync lock object</summary>
  775. private readonly object m_ParcelACLLock = new object();
  776. /// <summary>Raised when the simulator responds to a <see cref="RequestParcelAccessList"/> request</summary>
  777. public event EventHandler<ParcelAccessListReplyEventArgs> ParcelAccessListReply
  778. {
  779. add { lock (m_ParcelACLLock) { m_ParcelACL += value; } }
  780. remove { lock (m_ParcelACLLock) { m_ParcelACL -= value; } }
  781. }
  782. /// <summary>The event subscribers. null if no subcribers</summary>
  783. private EventHandler<ParcelObjectOwnersReplyEventArgs> m_ParcelObjectOwnersReply;
  784. /// <summary>Raises the ParcelObjectOwnersReply event</summary>
  785. /// <param name="e">A ParcelObjectOwnersReplyEventArgs object containing the
  786. /// data returned from the simulator</param>
  787. protected virtual void OnParcelObjectOwnersReply(ParcelObjectOwnersReplyEventArgs e)
  788. {
  789. EventHandler<ParcelObjectOwnersReplyEventArgs> handler = m_ParcelObjectOwnersReply;
  790. if (handler != null)
  791. handler(this, e);
  792. }
  793. /// <summary>Thread sync lock object</summary>
  794. private readonly object m_ParcelObjectOwnersLock = new object();
  795. /// <summary>Raised when the simulator responds to a <see cref="RequestObjectOwners"/> request</summary>
  796. public event EventHandler<ParcelObjectOwnersReplyEventArgs> ParcelObjectOwnersReply
  797. {
  798. add { lock (m_ParcelObjectOwnersLock) { m_ParcelObjectOwnersReply += value; } }
  799. remove { lock (m_ParcelObjectOwnersLock) { m_ParcelObjectOwnersReply -= value; } }
  800. }
  801. /// <summary>The event subscribers. null if no subcribers</summary>
  802. private EventHandler<SimParcelsDownloadedEventArgs> m_SimParcelsDownloaded;
  803. /// <summary>Raises the SimParcelsDownloaded event</summary>
  804. /// <param name="e">A SimParcelsDownloadedEventArgs object containing the
  805. /// data returned from the simulator</param>
  806. protected virtual void OnSimParcelsDownloaded(SimParcelsDownloadedEventArgs e)
  807. {
  808. EventHandler<SimParcelsDownloadedEventArgs> handler = m_SimParcelsDownloaded;
  809. if (handler != null)
  810. handler(this, e);
  811. }
  812. /// <summary>Thread sync lock object</summary>
  813. private readonly object m_SimParcelsDownloadedLock = new object();
  814. /// <summary>Raised when the simulator responds to a <see cref="RequestAllSimParcels"/> request</summary>
  815. public event EventHandler<SimParcelsDownloadedEventArgs> SimParcelsDownloaded
  816. {
  817. add { lock (m_SimParcelsDownloadedLock) { m_SimParcelsDownloaded += value; } }
  818. remove { lock (m_SimParcelsDownloadedLock) { m_SimParcelsDownloaded -= value; } }
  819. }
  820. /// <summary>The event subscribers. null if no subcribers</summary>
  821. private EventHandler<ForceSelectObjectsReplyEventArgs> m_ForceSelectObjects;
  822. /// <summary>Raises the ForceSelectObjectsReply event</summary>
  823. /// <param name="e">A ForceSelectObjectsReplyEventArgs object containing the
  824. /// data returned from the simulator</param>
  825. protected virtual void OnForceSelectObjectsReply(ForceSelectObjectsReplyEventArgs e)
  826. {
  827. EventHandler<ForceSelectObjectsReplyEventArgs> handler = m_ForceSelectObjects;
  828. if (handler != null)
  829. handler(this, e);
  830. }
  831. /// <summary>Thread sync lock object</summary>
  832. private readonly object m_ForceSelectObjectsLock = new object();
  833. /// <summary>Raised when the simulator responds to a <see cref="RequestForceSelectObjects"/> request</summary>
  834. public event EventHandler<ForceSelectObjectsReplyEventArgs> ForceSelectObjectsReply
  835. {
  836. add { lock (m_ForceSelectObjectsLock) { m_ForceSelectObjects += value; } }
  837. remove { lock (m_ForceSelectObjectsLock) { m_ForceSelectObjects -= value; } }
  838. }
  839. /// <summary>The event subscribers. null if no subcribers</summary>
  840. private EventHandler<ParcelMediaUpdateReplyEventArgs> m_ParcelMediaUpdateReply;
  841. /// <summary>Raises the ParcelMediaUpdateReply event</summary>
  842. /// <param name="e">A ParcelMediaUpdateReplyEventArgs object containing the
  843. /// data returned from the simulator</param>
  844. protected virtual void OnParcelMediaUpdateReply(ParcelMediaUpdateReplyEventArgs e)
  845. {
  846. EventHandler<ParcelMediaUpdateReplyEventArgs> handler = m_ParcelMediaUpdateReply;
  847. if (handler != null)
  848. handler(this, e);
  849. }
  850. /// <summary>Thread sync lock object</summary>
  851. private readonly object m_ParcelMediaUpdateReplyLock = new object();
  852. /// <summary>Raised when the simulator responds to a Parcel Update request</summary>
  853. public event EventHandler<ParcelMediaUpdateReplyEventArgs> ParcelMediaUpdateReply
  854. {
  855. add { lock (m_ParcelMediaUpdateReplyLock) { m_ParcelMediaUpdateReply += value; } }
  856. remove { lock (m_ParcelMediaUpdateReplyLock) { m_ParcelMediaUpdateReply -= value; } }
  857. }
  858. /// <summary>The event subscribers. null if no subcribers</summary>
  859. private EventHandler<ParcelMediaCommandEventArgs> m_ParcelMediaCommand;
  860. /// <summary>Raises the ParcelMediaCommand event</summary>
  861. /// <param name="e">A ParcelMediaCommandEventArgs object containing the
  862. /// data returned from the simulator</param>
  863. protected virtual void OnParcelMediaCommand(ParcelMediaCommandEventArgs e)
  864. {
  865. EventHandler<ParcelMediaCommandEventArgs> handler = m_ParcelMediaCommand;
  866. if (handler != null)
  867. handler(this, e);
  868. }
  869. /// <summary>Thread sync lock object</summary>
  870. private readonly object m_ParcelMediaCommandLock = new object();
  871. /// <summary>Raised when the parcel your agent is located sends a ParcelMediaCommand</summary>
  872. public event EventHandler<ParcelMediaCommandEventArgs> ParcelMediaCommand
  873. {
  874. add { lock (m_ParcelMediaCommandLock) { m_ParcelMediaCommand += value; } }
  875. remove { lock (m_ParcelMediaCommandLock) { m_ParcelMediaCommand -= value; } }
  876. }
  877. #endregion Delegates
  878. private GridClient Client;
  879. private AutoResetEvent WaitForSimParcel;
  880. #region Public Methods
  881. /// <summary>
  882. /// Default constructor
  883. /// </summary>
  884. /// <param name="client">A reference to the GridClient object</param>
  885. public ParcelManager(GridClient client)
  886. {
  887. Client = client;
  888. // Setup the callbacks
  889. Client.Network.RegisterCallback(PacketType.ParcelInfoReply, ParcelInfoReplyHandler);
  890. Client.Network.RegisterEventCallback("ParcelObjectOwnersReply", new Caps.EventQueueCallback(ParcelObjectOwnersReplyHandler));
  891. // CAPS packet handler, to allow for Media Data not contained in the message template
  892. Client.Network.RegisterEventCallback("ParcelProperties", new Caps.EventQueueCallback(ParcelPropertiesReplyHandler));
  893. Client.Network.RegisterCallback(PacketType.ParcelDwellReply, ParcelDwellReplyHandler);
  894. Client.Network.RegisterCallback(PacketType.ParcelAccessListReply, ParcelAccessListReplyHandler);
  895. Client.Network.RegisterCallback(PacketType.ForceObjectSelect, SelectParcelObjectsReplyHandler);
  896. Client.Network.RegisterCallback(PacketType.ParcelMediaUpdate, ParcelMediaUpdateHandler);
  897. Client.Network.RegisterCallback(PacketType.ParcelOverlay, ParcelOverlayHandler);
  898. Client.Network.RegisterCallback(PacketType.ParcelMediaCommandMessage, ParcelMediaCommandMessagePacketHandler);
  899. }
  900. /// <summary>
  901. /// Request basic information for a single parcel
  902. /// </summary>
  903. /// <param name="parcelID">Simulator-local ID of the parcel</param>
  904. public void RequestParcelInfo(UUID parcelID)
  905. {
  906. ParcelInfoRequestPacket request = new ParcelInfoRequestPacket();
  907. request.AgentData.AgentID = Client.Self.AgentID;
  908. request.AgentData.SessionID = Client.Self.SessionID;
  909. request.Data.ParcelID = parcelID;
  910. Client.Network.SendPacket(request);
  911. }
  912. /// <summary>
  913. /// Request properties of a single parcel
  914. /// </summary>
  915. /// <param name="simulator">Simulator containing the parcel</param>
  916. /// <param name="localID">Simulator-local ID of the parcel</param>
  917. /// <param name="sequenceID">An arbitrary integer that will be returned
  918. /// with the ParcelProperties reply, useful for distinguishing between
  919. /// multiple simultaneous requests</param>
  920. public void RequestParcelProperties(Simulator simulator, int localID, int sequenceID)
  921. {
  922. ParcelPropertiesRequestByIDPacket request = new ParcelPropertiesRequestByIDPacket();
  923. request.AgentData.AgentID = Client.Self.AgentID;
  924. request.AgentData.SessionID = Client.Self.SessionID;
  925. request.ParcelData.LocalID = localID;
  926. request.ParcelData.SequenceID = sequenceID;
  927. Client.Network.SendPacket(request, simulator);
  928. }
  929. /// <summary>
  930. /// Request the access list for a single parcel
  931. /// </summary>
  932. /// <param name="simulator">Simulator containing the parcel</param>
  933. /// <param name="localID">Simulator-local ID of the parcel</param>
  934. /// <param name="sequenceID">An arbitrary integer that will be returned
  935. /// with the ParcelAccessList reply, useful for distinguishing between
  936. /// multiple simultaneous requests</param>
  937. /// <param name="flags"></param>
  938. public void RequestParcelAccessList(Simulator simulator, int localID, AccessList flags, int sequenceID)
  939. {
  940. ParcelAccessListRequestPacket request = new ParcelAccessListRequestPacket();
  941. request.AgentData.AgentID = Client.Self.AgentID;
  942. request.AgentData.SessionID = Client.Self.SessionID;
  943. request.Data.LocalID = localID;
  944. request.Data.Flags = (uint)flags;
  945. request.Data.SequenceID = sequenceID;
  946. Client.Network.SendPacket(request, simulator);
  947. }
  948. /// <summary>
  949. /// Request properties of parcels using a bounding box selection
  950. /// </summary>
  951. /// <param name="simulator">Simulator containing the parcel</param>
  952. /// <param name="north">Northern boundary of the parcel selection</param>
  953. /// <param name="east">Eastern boundary of the parcel selection</param>
  954. /// <param name="south">Southern boundary of the parcel selection</param>
  955. /// <param name="west">Western boundary of the parcel selection</param>
  956. /// <param name="sequenceID">An arbitrary integer that will be returned
  957. /// with the ParcelProperties reply, useful for distinguishing between
  958. /// different types of parcel property requests</param>
  959. /// <param name="snapSelection">A boolean that is returned with the
  960. /// ParcelProperties reply, useful for snapping focus to a single
  961. /// parcel</param>
  962. public void RequestParcelProperties(Simulator simulator, float north, float east, float south, float west,
  963. int sequenceID, bool snapSelection)
  964. {
  965. ParcelPropertiesRequestPacket request = new ParcelPropertiesRequestPacket();
  966. request.AgentData.AgentID = Client.Self.AgentID;
  967. request.AgentData.SessionID = Client.Self.SessionID;
  968. request.ParcelData.North = north;
  969. request.ParcelData.East = east;
  970. request.ParcelData.South = south;
  971. request.ParcelData.West = west;
  972. request.ParcelData.SequenceID = sequenceID;
  973. request.ParcelData.SnapSelection = snapSelection;
  974. Client.Network.SendPacket(request, simulator);
  975. }
  976. /// <summary>
  977. /// Request all simulator parcel properties (used for populating the <code>Simulator.Parcels</code>
  978. /// dictionary)
  979. /// </summary>
  980. /// <param name="simulator">Simulator to request parcels from (must be connected)</param>
  981. public void RequestAllSimParcels(Simulator simulator)
  982. {
  983. RequestAllSimParcels(simulator, false, 750);
  984. }
  985. /// <summary>
  986. /// Request all simulator parcel properties (used for populating the <code>Simulator.Parcels</code>
  987. /// dictionary)
  988. /// </summary>
  989. /// <param name="simulator">Simulator to request parcels from (must be connected)</param>
  990. /// <param name="refresh">If TRUE, will force a full refresh</param>
  991. /// <param name="msDelay">Number of milliseconds to pause in between each request</param>
  992. public void RequestAllSimParcels(Simulator simulator, bool refresh, int msDelay)
  993. {
  994. if (simulator.DownloadingParcelMap)
  995. {
  996. Logger.Log("Already downloading parcels in " + simulator.Name, Helpers.LogLevel.Info, Client);
  997. return;
  998. }
  999. else
  1000. {
  1001. simulator.DownloadingParcelMap = true;
  1002. WaitForSimParcel = new AutoResetEvent(false);
  1003. }
  1004. if (refresh)
  1005. {
  1006. for (int y = 0; y < 64; y++)
  1007. for (int x = 0; x < 64; x++)
  1008. simulator.ParcelMap[y, x] = 0;
  1009. }
  1010. Thread th = new Thread(delegate()
  1011. {
  1012. int count = 0, timeouts = 0, y, x;
  1013. for (y = 0; y < 64; y++)
  1014. {
  1015. for (x = 0; x < 64; x++)
  1016. {
  1017. if (!Client.Network.Connected)
  1018. return;
  1019. if (simulator.ParcelMap[y, x] == 0)
  1020. {
  1021. Client.Parcels.RequestParcelProperties(simulator,
  1022. (y + 1) * 4.0f, (x + 1) * 4.0f,
  1023. y * 4.0f, x * 4.0f, int.MaxValue, false);
  1024. // Wait the given amount of time for a reply before sending the next request
  1025. if (!WaitForSimParcel.WaitOne(msDelay, false))
  1026. ++timeouts;
  1027. ++count;
  1028. }
  1029. }
  1030. }
  1031. Logger.Log(String.Format(
  1032. "Full simulator parcel information retrieved. Sent {0} parcel requests. Current outgoing queue: {1}, Retry Count {2}",
  1033. count, Client.Network.OutboxCount, timeouts), Helpers.LogLevel.Info, Client);
  1034. simulator.DownloadingParcelMap = false;
  1035. });
  1036. th.Start();
  1037. }
  1038. /// <summary>
  1039. /// Request the dwell value for a parcel
  1040. /// </summary>
  1041. /// <param name="simulator">Simulator containing the parcel</param>
  1042. /// <param name="localID">Simulator-local ID of the parcel</param>
  1043. public void RequestDwell(Simulator simulator, int localID)
  1044. {
  1045. ParcelDwellRequestPacket request = new ParcelDwellRequestPacket();
  1046. request.AgentData.AgentID = Client.Self.AgentID;
  1047. request.AgentData.SessionID = Client.Self.SessionID;
  1048. request.Data.LocalID = localID;
  1049. request.Data.ParcelID = UUID.Zero; // Not used by clients
  1050. Client.Network.SendPacket(request, simulator);
  1051. }
  1052. /// <summary>
  1053. /// Send a request to Purchase a parcel of land
  1054. /// </summary>
  1055. /// <param name="simulator">The Simulator the parcel is located in</param>
  1056. /// <param name="localID">The parcels region specific local ID</param>
  1057. /// <param name="forGroup">true if this parcel is being purchased by a group</param>
  1058. /// <param name="groupID">The groups <seealso cref="T:OpenMetaverse.UUID"/></param>
  1059. /// <param name="removeContribution">true to remove tier contribution if purchase is successful</param>
  1060. /// <param name="parcelArea">The parcels size</param>
  1061. /// <param name="parcelPrice">The purchase price of the parcel</param>
  1062. /// <returns></returns>
  1063. public void Buy(Simulator simulator, int localID, bool forGroup, UUID groupID,
  1064. bool removeContribution, int parcelArea, int parcelPrice)
  1065. {
  1066. ParcelBuyPacket request = new ParcelBuyPacket();
  1067. request.AgentData.AgentID = Client.Self.AgentID;
  1068. request.AgentData.SessionID = Client.Self.SessionID;
  1069. request.Data.Final = true;
  1070. request.Data.GroupID = groupID;
  1071. request.Data.LocalID = localID;
  1072. request.Data.IsGroupOwned = forGroup;
  1073. request.Data.RemoveContribution = removeContribution;
  1074. request.ParcelData.Area = parcelArea;
  1075. request.ParcelData.Price = parcelPrice;
  1076. Client.Network.SendPacket(request, simulator);
  1077. }
  1078. /// <summary>
  1079. /// Reclaim a parcel of land
  1080. /// </summary>
  1081. /// <param name="simulator">The simulator the parcel is in</param>
  1082. /// <param name="localID">The parcels region specific local ID</param>
  1083. public void Reclaim(Simulator simulator, int localID)
  1084. {
  1085. ParcelReclaimPacket request = new ParcelReclaimPacket();
  1086. request.AgentData.AgentID = Client.Self.AgentID;
  1087. request.AgentData.SessionID = Client.Self.SessionID;
  1088. request.Data.LocalID = localID;
  1089. Client.Network.SendPacket(request, simulator);
  1090. }
  1091. /// <summary>
  1092. /// Deed a parcel to a group
  1093. /// </summary>
  1094. /// <param name="simulator">The simulator the parcel is in</param>
  1095. /// <param name="localID">The parcels region specific local ID</param>
  1096. /// <param name="groupID">The groups <seealso cref="T:OpenMetaverse.UUID"/></param>
  1097. public void DeedToGroup(Simulator simulator, int localID, UUID groupID)
  1098. {
  1099. ParcelDeedToGroupPacket request = new ParcelDeedToGroupPacket();
  1100. request.AgentData.AgentID = Client.Self.AgentID;
  1101. request.AgentData.SessionID = Client.Self.SessionID;
  1102. request.Data.LocalID = localID;
  1103. request.Data.GroupID = groupID;
  1104. Client.Network.SendPacket(request, simulator);
  1105. }
  1106. /// <summary>
  1107. /// Request prim owners of a parcel of land.
  1108. /// </summary>
  1109. /// <param name="simulator">Simulator parcel is in</param>
  1110. /// <param name="localID">The parcels region specific local ID</param>
  1111. public void RequestObjectOwners(Simulator simulator, int localID)
  1112. {
  1113. ParcelObjectOwnersRequestPacket request = new ParcelObjectOwnersRequestPacket();
  1114. request.AgentData.AgentID = Client.Self.AgentID;
  1115. request.AgentData.SessionID = Client.Self.SessionID;
  1116. request.ParcelData.LocalID = localID;
  1117. Client.Network.SendPacket(request, simulator);
  1118. }
  1119. /// <summary>
  1120. /// Return objects from a parcel
  1121. /// </summary>
  1122. /// <param name="simulator">Simulator parcel is in</param>
  1123. /// <param name="localID">The parcels region specific local ID</param>
  1124. /// <param name="type">the type of objects to return, <seealso cref="T:OpenMetaverse.ObjectReturnType"/></param>
  1125. /// <param name="ownerIDs">A list containing object owners <seealso cref="OpenMetaverse.UUID"/>s to return</param>
  1126. public void ReturnObjects(Simulator simulator, int localID, ObjectReturnType type, List<UUID> ownerIDs)
  1127. {
  1128. ParcelReturnObjectsPacket request = new ParcelReturnObjectsPacket();
  1129. request.AgentData.AgentID = Client.Self.AgentID;
  1130. request.AgentData.SessionID = Client.Self.SessionID;
  1131. request.ParcelData.LocalID = localID;
  1132. request.ParcelData.ReturnType = (uint)type;
  1133. // A single null TaskID is (not) used for parcel object returns
  1134. request.TaskIDs = new ParcelReturnObjectsPacket.TaskIDsBlock[1];
  1135. request.TaskIDs[0] = new ParcelReturnObjectsPacket.TaskIDsBlock();
  1136. request.TaskIDs[0].TaskID = UUID.Zero;
  1137. // Convert the list of owner UUIDs to packet blocks if a list is given
  1138. if (ownerIDs != null)
  1139. {
  1140. request.OwnerIDs = new ParcelReturnObjectsPacket.OwnerIDsBlock[ownerIDs.Count];
  1141. for (int i = 0; i < ownerIDs.Count; i++)
  1142. {
  1143. request.OwnerIDs[i] = new ParcelReturnObjectsPacket.OwnerIDsBlock();
  1144. request.OwnerIDs[i].OwnerID = ownerIDs[i];
  1145. }
  1146. }
  1147. else
  1148. {
  1149. request.OwnerIDs = new ParcelReturnObjectsPacket.OwnerIDsBlock[0];
  1150. }
  1151. Client.Network.SendPacket(request, simulator);
  1152. }
  1153. /// <summary>
  1154. /// Subdivide (split) a parcel
  1155. /// </summary>
  1156. /// <param name="simulator"></param>
  1157. /// <param name="west"></param>
  1158. /// <param name="south"></param>
  1159. /// <param name="east"></param>
  1160. /// <param name="north"></param>
  1161. public void ParcelSubdivide(Simulator simulator, float west, float south, float east, float north)
  1162. {
  1163. ParcelDividePacket divide = new ParcelDividePacket();
  1164. divide.AgentData.AgentID = Client.Self.AgentID;
  1165. divide.AgentData.SessionID = Client.Self.SessionID;
  1166. divide.ParcelData.East = east;
  1167. divide.ParcelData.North = north;
  1168. divide.ParcelData.South = south;
  1169. divide.ParcelData.West = west;
  1170. Client.Network.SendPacket(divide, simulator);
  1171. }
  1172. /// <summary>
  1173. /// Join two parcels of land creating a single parcel
  1174. /// </summary>
  1175. /// <param name="simulator"></param>
  1176. /// <param name="west"></param>
  1177. /// <param name="south"></param>
  1178. /// <param name="east"></param>
  1179. /// <param name="north"></param>
  1180. public void ParcelJoin(Simulator simulator, float west, float south, float east, float north)
  1181. {
  1182. ParcelJoinPacket join = new ParcelJoinPacket();
  1183. join.AgentData.AgentID = Client.Self.AgentID;
  1184. join.AgentData.SessionID = Client.Self.SessionID;
  1185. join.ParcelData.East = east;
  1186. join.ParcelData.North = north;
  1187. join.ParcelData.South = south;
  1188. join.ParcelData.West = west;
  1189. Client.Network.SendPacket(join, simulator);
  1190. }
  1191. /// <summary>
  1192. /// Get a parcels LocalID
  1193. /// </summary>
  1194. /// <param name="simulator">Simulator parcel is in</param>
  1195. /// <param name="position">Vector3 position in simulator (Z not used)</param>
  1196. /// <returns>0 on failure, or parcel LocalID on success.</returns>
  1197. /// <remarks>A call to <code>Parcels.RequestAllSimParcels</code> is required to populate map and
  1198. /// dictionary.</remarks>
  1199. public int GetParcelLocalID(Simulator simulator, Vector3 position)
  1200. {
  1201. if (simulator.ParcelMap[(byte)position.Y / 4, (byte)position.X / 4] > 0)
  1202. {
  1203. return simulator.ParcelMap[(byte)position.Y / 4, (byte)position.X / 4];
  1204. }
  1205. else
  1206. {
  1207. Logger.Log(String.Format("ParcelMap returned an default/invalid value for location {0}/{1} Did you use RequestAllSimParcels() to populate the dictionaries?", (byte)position.Y / 4, (byte)position.X / 4 ), Helpers.LogLevel.Warning);
  1208. return 0;
  1209. }
  1210. }
  1211. /// <summary>
  1212. /// Terraform (raise, lower, etc) an area or whole parcel of land
  1213. /// </summary>
  1214. /// <param name="simulator">Simulator land area is in.</param>
  1215. /// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
  1216. /// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
  1217. /// <param name="brushSize">Size of area to modify</param>
  1218. /// <returns>true on successful request sent.</returns>
  1219. /// <remarks>Settings.STORE_LAND_PATCHES must be true,
  1220. /// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
  1221. public bool Terraform(Simulator simulator, int localID, TerraformAction action, TerraformBrushSize brushSize)
  1222. {
  1223. return Terraform(simulator, localID, 0f, 0f, 0f, 0f, action, brushSize, 1);
  1224. }
  1225. /// <summary>
  1226. /// Terraform (raise, lower, etc) an area or whole parcel of land
  1227. /// </summary>
  1228. /// <param name="simulator">Simulator land area is in.</param>
  1229. /// <param name="west">west border of area to modify</param>
  1230. /// <param name="south">south border of area to modify</param>
  1231. /// <param name="east">east border of area to modify</param>
  1232. /// <param name="north">north border of area to modify</param>
  1233. /// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
  1234. /// <param name="brushSize">Size of area to modify</param>
  1235. /// <returns>true on successful request sent.</returns>
  1236. /// <remarks>Settings.STORE_LAND_PATCHES must be true,
  1237. /// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
  1238. public bool Terraform(Simulator simulator, float west, float south, float east, float north,
  1239. TerraformAction action, TerraformBrushSize brushSize)
  1240. {
  1241. return Terraform(simulator, -1, west, south, east, north, action, brushSize, 1);
  1242. }
  1243. /// <summary>
  1244. /// Terraform (raise, lower, etc) an area or whole parcel of land
  1245. /// </summary>
  1246. /// <param name="simulator">Simulator land area is in.</param>
  1247. /// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
  1248. /// <param name="west">west border of area to modify</param>
  1249. /// <param name="south">south border of area to modify</param>
  1250. /// <param name="east">east border of area to modify</param>
  1251. /// <param name="north">north border of area to modify</param>
  1252. /// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
  1253. /// <param name="brushSize">Size of area to modify</param>
  1254. /// <param name="seconds">How many meters + or - to lower, 1 = 1 meter</param>
  1255. /// <returns>true on successful request sent.</returns>
  1256. /// <remarks>Settings.STORE_LAND_PATCHES must be true,
  1257. /// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
  1258. public bool Terraform(Simulator simulator, int localID, float west, float south, float east, float north,
  1259. TerraformAction action, TerraformBrushSize brushSize, int seconds)
  1260. {
  1261. float height = 0f;
  1262. int x, y;
  1263. if (localID == -1)
  1264. {
  1265. x = (int)east - (int)west / 2;
  1266. y = (int)north - (int)south / 2;
  1267. }
  1268. else
  1269. {
  1270. Parcel p;
  1271. if (!simulator.Parcels.TryGetValue(localID, out p))
  1272. {
  1273. Logger.Log(String.Format("Can't find parcel {0} in simulator {1}", localID, simulator),
  1274. Helpers.LogLevel.Warning, Client);
  1275. return false;
  1276. }
  1277. x = (int)p.AABBMax.X - (int)p.AABBMin.X / 2;
  1278. y = (int)p.AABBMax.Y - (int)p.AABBMin.Y / 2;
  1279. }
  1280. if (!simulator.TerrainHeightAtPoint(x, y, out height))
  1281. {
  1282. Logger.Log("Land Patch not stored for location", Helpers.LogLevel.Warning, Client);
  1283. return false;
  1284. }
  1285. Terraform(simulator, localID, west, south, east, north, action, brushSize, seconds, height);
  1286. return true;
  1287. }
  1288. /// <summary>
  1289. /// Terraform (raise, lower, etc) an area or whole parcel of land
  1290. /// </summary>
  1291. /// <param name="simulator">Simulator land area is in.</param>
  1292. /// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
  1293. /// <param name="west">west border of area to modify</param>
  1294. /// <param name="south">south border of area to modify</param>
  1295. /// <param name="east">east border of area to modify</param>
  1296. /// <param name="north">north border of area to modify</param>
  1297. /// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
  1298. /// <param name="brushSize">Size of area to modify</param>
  1299. /// <param name="seconds">How many meters + or - to lower, 1 = 1 meter</param>
  1300. /// <param name="height">Height at which the terraform operation is acting at</param>
  1301. public void Terraform(Simulator simulator, int localID, float west, float south, float east, float north,
  1302. TerraformAction action, TerraformBrushSize brushSize, int seconds, float height)
  1303. {
  1304. ModifyLandPacket land = new ModifyLandPacket();
  1305. land.AgentData.AgentID = Client.Self.AgentID;
  1306. land.AgentData.SessionID = Client.Self.SessionID;
  1307. land.ModifyBlock.Action = (byte)action;
  1308. land.ModifyBlock.BrushSize = (byte)brushSize;
  1309. land.ModifyBlock.Seconds = seconds;
  1310. land.ModifyBlock.Height = height;
  1311. land.ParcelData = new ModifyLandPacket.ParcelDataBlock[1];
  1312. land.ParcelData[0] = new ModifyLandPacket.ParcelDataBlock();
  1313. land.ParcelData[0].LocalID = localID;
  1314. land.ParcelData[0].West = west;
  1315. land.ParcelData[0].South = south;
  1316. land.ParcelData[0].East = east;
  1317. land.ParcelData[0].North = north;
  1318. land.ModifyBlockExtended = new ModifyLandPacket.ModifyBlockExtendedBlock[1];
  1319. land.ModifyBlockExtended[0] = new ModifyLandPacket.ModifyBlockExtendedBlock();
  1320. land.ModifyBlockExtended[0].BrushSize = (float)brushSize;
  1321. Client.Network.SendPacket(land, simulator);
  1322. }
  1323. /// <summary>
  1324. /// Sends a request to the simulator to return a list of objects owned by specific owners
  1325. /// </summary>
  1326. /// <param name="localID">Simulator local ID of parcel</param>
  1327. /// <param name="selectType">Owners, Others, Etc</param>
  1328. /// <param name="ownerID">List containing keys of avatars objects to select;
  1329. /// if List is null will return Objects of type <c>selectType</c></param>
  1330. /// <remarks>Response data is returned in the event <seealso cref="E:ForceSelectObjectsReply"/></remarks>
  1331. public void RequestSelectObjects(int localID, ObjectReturnType selectType, UUID ownerID)
  1332. {
  1333. ParcelSelectObjectsPacket select = new ParcelSelectObjectsPacket();
  1334. select.AgentData.AgentID = Client.Self.AgentID;
  1335. select.AgentData.SessionID = Client.Self.SessionID;
  1336. select.ParcelData.LocalID = localID;
  1337. select.ParcelData.ReturnType = (uint)selectType;
  1338. select.ReturnIDs = new ParcelSelectObjectsPacket.ReturnIDsBlock[1];
  1339. select.ReturnIDs[0] = new ParcelSelectObjectsPacket.ReturnIDsBlock();
  1340. select.ReturnIDs[0].ReturnID = ownerID;
  1341. Client.Network.SendPacket(select);
  1342. }
  1343. /// <summary>
  1344. /// Eject and optionally ban a user from a parcel
  1345. /// </summary>
  1346. /// <param name="targetID">target key of avatar to eject</param>
  1347. /// <param name="ban">true to also ban target</param>
  1348. public void EjectUser(UUID targetID, bool ban)
  1349. {
  1350. EjectUserPacket eject = new EjectUserPacket();
  1351. eject.AgentData.AgentID = Client.Self.AgentID;
  1352. eject.AgentData.SessionID = Client.Self.SessionID;
  1353. eject.Data.TargetID = targetID;
  1354. if (ban) eject.Data.Flags = 1;
  1355. else eject.Data.Flags = 0;
  1356. Client.Network.SendPacket(eject);
  1357. }
  1358. /// <summary>
  1359. /// Freeze or unfreeze an avatar over your land
  1360. /// </summary>
  1361. /// <param name="targetID">target key to freeze</param>
  1362. /// <param name="freeze">true to freeze, false to unfreeze</param>
  1363. public void FreezeUser(UUID targetID, bool freeze)
  1364. {
  1365. FreezeUserPacket frz = new FreezeUserPacket();
  1366. frz.AgentData.AgentID = Client.Self.AgentID;
  1367. frz.AgentData.SessionID = Client.Self.SessionID;
  1368. frz.Data.TargetID = targetID;
  1369. if (freeze) frz.Data.Flags = 0;
  1370. else frz.Data.Flags = 1;
  1371. Client.Network.SendPacket(frz);
  1372. }
  1373. /// <summary>
  1374. /// Abandon a parcel of land
  1375. /// </summary>
  1376. /// <param name="simulator">Simulator parcel is in</param>
  1377. /// <param name="localID">Simulator local ID of parcel</param>
  1378. public void ReleaseParcel(Simulator simulator, int localID)
  1379. {
  1380. ParcelReleasePacket abandon = new ParcelReleasePacket();
  1381. abandon.AgentData.AgentID = Client.Self.AgentID;
  1382. abandon.AgentData.SessionID = Client.Self.SessionID;
  1383. abandon.Data.LocalID = localID;
  1384. Client.Network.SendPacket(abandon, simulator);
  1385. }
  1386. /// <summary>
  1387. /// Requests the UUID of the parcel in a remote region at a specified location
  1388. /// </summary>
  1389. /// <param name="location">Location of the parcel in the remote region</param>
  1390. /// <param name="regionHandle">Remote region handle</param>
  1391. /// <param name="regionID">Remote region UUID</param>
  1392. /// <returns>If successful UUID of the remote parcel, UUID.Zero otherwise</returns>
  1393. public UUID RequestRemoteParcelID(Vector3 location, ulong regionHandle, UUID regionID)
  1394. {
  1395. if (Client.Network.CurrentSim == null || Client.Network.CurrentSim.Caps == null)
  1396. return UUID.Zero;
  1397. Uri url = Client.Network.CurrentSim.Caps.CapabilityURI("RemoteParcelRequest");
  1398. if (url != null)
  1399. {
  1400. RemoteParcelRequestRequest msg = new RemoteParcelRequestRequest();
  1401. msg.Location = location;
  1402. msg.RegionHandle = regionHandle;
  1403. msg.RegionID = regionID;
  1404. try
  1405. {
  1406. CapsClient request = new CapsClient(url);
  1407. OSD result = request.GetResponse(msg.Serialize(), OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);
  1408. RemoteParcelRequestReply response = new RemoteParcelRequestReply();
  1409. response.Deserialize((OSDMap)result);
  1410. return response.ParcelID;
  1411. }
  1412. catch (Exception)
  1413. {
  1414. Logger.Log("Failed to fetch remote parcel ID", Helpers.LogLevel.Debug, Client);
  1415. }
  1416. }
  1417. return UUID.Zero;
  1418. }
  1419. /// <summary>
  1420. /// Retrieves information on resources used by the parcel
  1421. /// </summary>
  1422. /// <param name="parcelID">UUID of the parcel</param>
  1423. /// <param name="getDetails">Should per object resource usage be requested</param>
  1424. /// <param name="callback">Callback invoked when the request is complete</param>
  1425. public void GetParcelResouces(UUID parcelID, bool getDetails, LandResourcesCallback callback)
  1426. {
  1427. try
  1428. {
  1429. Uri url = Client.Network.CurrentSim.Caps.CapabilityURI("LandResources");
  1430. CapsClient request = new CapsClient(url);
  1431. request.OnComplete += delegate(CapsClient client, OSD result, Exception error)
  1432. {
  1433. try
  1434. {
  1435. if (result == null || error != null)
  1436. {
  1437. callback(false, null);
  1438. }
  1439. LandResourcesMessage response = new LandResourcesMessage();
  1440. response.Deserialize((OSDMap)result);
  1441. CapsClient summaryRequest = new CapsClient(response.ScriptResourceSummary);
  1442. OSD summaryResponse = summaryRequest.GetResponse(Client.Settings.CAPS_TIMEOUT);
  1443. LandResourcesInfo res = new LandResourcesInfo();
  1444. res.Deserialize((OSDMap)summaryResponse);
  1445. if (response.ScriptResourceDetails != null && getDetails)
  1446. {
  1447. CapsClient detailRequest = new CapsClient(response.ScriptResourceDetails);
  1448. OSD detailResponse = detailRequest.GetResponse(Client.Settings.CAPS_TIMEOUT);
  1449. res.Deserialize((OSDMap)detailResponse);
  1450. }
  1451. callback(true, res);
  1452. }
  1453. catch (Exception ex)
  1454. {
  1455. Logger.Log("Failed fetching land resources", Helpers.LogLevel.Error, Client, ex);
  1456. callback(false, null);
  1457. }
  1458. };
  1459. LandResourcesRequest param = new LandResourcesRequest();
  1460. param.ParcelID = parcelID;
  1461. request.BeginGetResponse(param.Serialize(), OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);
  1462. }
  1463. catch (Exception ex)
  1464. {
  1465. Logger.Log("Failed fetching land resources:", Helpers.LogLevel.Error, Client, ex);
  1466. callback(false, null);
  1467. }
  1468. }
  1469. #endregion Public Methods
  1470. #region Packet Handlers
  1471. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1472. /// <param name="sender">The sender</param>
  1473. /// <param name="e">The EventArgs object containing the packet data</param>
  1474. /// <remarks>Raises the <see cref="ParcelDwellReply"/> event</remarks>
  1475. protected void ParcelDwellReplyHandler(object sender, PacketReceivedEventArgs e)
  1476. {
  1477. if (m_DwellReply != null || Client.Settings.ALWAYS_REQUEST_PARCEL_DWELL == true)
  1478. {
  1479. Packet packet = e.Packet;
  1480. Simulator simulator = e.Simulator;
  1481. ParcelDwellReplyPacket dwell = (ParcelDwellReplyPacket)packet;
  1482. lock (simulator.Parcels.Dictionary)
  1483. {
  1484. if (simulator.Parcels.Dictionary.ContainsKey(dwell.Data.LocalID))
  1485. {
  1486. Parcel parcel = simulator.Parcels.Dictionary[dwell.Data.LocalID];
  1487. parcel.Dwell = dwell.Data.Dwell;
  1488. simulator.Parcels.Dictionary[dwell.Data.LocalID] = parcel;
  1489. }
  1490. }
  1491. if (m_DwellReply != null)
  1492. {
  1493. OnParcelDwellReply(new ParcelDwellReplyEventArgs(dwell.Data.ParcelID, dwell.Data.LocalID, dwell.Data.Dwell));
  1494. }
  1495. }
  1496. }
  1497. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1498. /// <param name="sender">The sender</param>
  1499. /// <param name="e">The EventArgs object containing the packet data</param>
  1500. /// <remarks>Raises the <see cref="ParcelInfoReply"/> event</remarks>
  1501. protected void ParcelInfoReplyHandler(object sender, PacketReceivedEventArgs e)
  1502. {
  1503. if (m_ParcelInfo != null)
  1504. {
  1505. Packet packet = e.Packet;
  1506. ParcelInfoReplyPacket info = (ParcelInfoReplyPacket)packet;
  1507. ParcelInfo parcelInfo = new ParcelInfo();
  1508. parcelInfo.ActualArea = info.Data.ActualArea;
  1509. parcelInfo.AuctionID = info.Data.AuctionID;
  1510. parcelInfo.BillableArea = info.Data.BillableArea;
  1511. parcelInfo.Description = Utils.BytesToString(info.Data.Desc);
  1512. parcelInfo.Dwell = info.Data.Dwell;
  1513. parcelInfo.GlobalX = info.Data.GlobalX;
  1514. parcelInfo.GlobalY = info.Data.GlobalY;
  1515. parcelInfo.GlobalZ = info.Data.GlobalZ;
  1516. parcelInfo.ID = info.Data.ParcelID;
  1517. parcelInfo.Mature = ((info.Data.Flags & 1) != 0) ? true : false;
  1518. parcelInfo.Name = Utils.BytesToString(info.Data.Name);
  1519. parcelInfo.OwnerID = info.Data.OwnerID;
  1520. parcelInfo.SalePrice = info.Data.SalePrice;
  1521. parcelInfo.SimName = Utils.BytesToString(info.Data.SimName);
  1522. parcelInfo.SnapshotID = info.Data.SnapshotID;
  1523. OnParcelInfoReply(new ParcelInfoReplyEventArgs(parcelInfo));
  1524. }
  1525. }
  1526. protected void ParcelPropertiesReplyHandler(string capsKey, IMessage message, Simulator simulator)
  1527. {
  1528. if (m_ParcelProperties != null || Client.Settings.PARCEL_TRACKING == true)
  1529. {
  1530. ParcelPropertiesMessage msg = (ParcelPropertiesMessage)message;
  1531. Parcel parcel = new Parcel(msg.LocalID);
  1532. parcel.AABBMax = msg.AABBMax;
  1533. parcel.AABBMin = msg.AABBMin;
  1534. parcel.Area = msg.Area;
  1535. parcel.AuctionID = msg.AuctionID;
  1536. parcel.AuthBuyerID = msg.AuthBuyerID;
  1537. parcel.Bitmap = msg.Bitmap;
  1538. parcel.Category = msg.Category;
  1539. parcel.ClaimDate = msg.ClaimDate;
  1540. parcel.ClaimPrice = msg.ClaimPrice;
  1541. parcel.Desc = msg.Desc;
  1542. parcel.Flags = msg.ParcelFlags;
  1543. parcel.GroupID = msg.GroupID;
  1544. parcel.GroupPrims = msg.GroupPrims;
  1545. parcel.IsGroupOwned = msg.IsGroupOwned;
  1546. parcel.Landing = msg.LandingType;
  1547. parcel.MaxPrims = msg.MaxPrims;
  1548. parcel.Media.MediaAutoScale = msg.MediaAutoScale;
  1549. parcel.Media.MediaID = msg.MediaID;
  1550. parcel.Media.MediaURL = msg.MediaURL;
  1551. parcel.MusicURL = msg.MusicURL;
  1552. parcel.Name = msg.Name;
  1553. parcel.OtherCleanTime = msg.OtherCleanTime;
  1554. parcel.OtherCount = msg.OtherCount;
  1555. parcel.OtherPrims = msg.OtherPrims;
  1556. parcel.OwnerID = msg.OwnerID;
  1557. parcel.OwnerPrims = msg.OwnerPrims;
  1558. parcel.ParcelPrimBonus = msg.ParcelPrimBonus;
  1559. parcel.PassHours = msg.PassHours;
  1560. parcel.PassPrice = msg.PassPrice;
  1561. parcel.PublicCount = msg.PublicCount;
  1562. parcel.RegionDenyAgeUnverified = msg.RegionDenyAgeUnverified;
  1563. parcel.RegionDenyAnonymous = msg.RegionDenyAnonymous;
  1564. parcel.RegionPushOverride = msg.RegionPushOverride;
  1565. parcel.RentPrice = msg.RentPrice;
  1566. ParcelResult result = msg.RequestResult;
  1567. parcel.SalePrice = msg.SalePrice;
  1568. int selectedPrims = msg.SelectedPrims;
  1569. parcel.SelfCount = msg.SelfCount;
  1570. int sequenceID = msg.SequenceID;
  1571. parcel.SimWideMaxPrims = msg.SimWideMaxPrims;
  1572. parcel.SimWideTotalPrims = msg.SimWideTotalPrims;
  1573. bool snapSelection = msg.SnapSelection;
  1574. parcel.SnapshotID = msg.SnapshotID;
  1575. parcel.Status = msg.Status;
  1576. parcel.TotalPrims = msg.TotalPrims;
  1577. parcel.UserLocation = msg.UserLocation;
  1578. parcel.UserLookAt = msg.UserLookAt;
  1579. parcel.Media.MediaDesc = msg.MediaDesc;
  1580. parcel.Media.MediaHeight = msg.MediaHeight;
  1581. parcel.Media.MediaWidth = msg.MediaWidth;
  1582. parcel.Media.MediaLoop = msg.MediaLoop;
  1583. parcel.Media.MediaType = msg.MediaType;
  1584. parcel.ObscureMedia = msg.ObscureMedia;
  1585. parcel.ObscureMusic = msg.ObscureMusic;
  1586. if (Client.Settings.PARCEL_TRACKING)
  1587. {
  1588. lock (simulator.Parcels.Dictionary)
  1589. simulator.Parcels.Dictionary[parcel.LocalID] = parcel;
  1590. bool set = false;
  1591. int y, x, index, bit;
  1592. for (y = 0; y < 64; y++)
  1593. {
  1594. for (x = 0; x < 64; x++)
  1595. {
  1596. index = (y * 64) + x;
  1597. bit = index % 8;
  1598. index >>= 3;
  1599. if ((parcel.Bitmap[index] & (1 << bit)) != 0)
  1600. {
  1601. simulator.ParcelMap[y, x] = parcel.LocalID;
  1602. set = true;
  1603. }
  1604. }
  1605. }
  1606. if (!set)
  1607. {
  1608. Logger.Log("Received a parcel with a bitmap that did not map to any locations",
  1609. Helpers.LogLevel.Warning);
  1610. }
  1611. }
  1612. if (sequenceID.Equals(int.MaxValue) && WaitForSimParcel != null)
  1613. WaitForSimParcel.Set();
  1614. // auto request acl, will be stored in parcel tracking dictionary if enabled
  1615. if (Client.Settings.ALWAYS_REQUEST_PARCEL_ACL)
  1616. Client.Parcels.RequestParcelAccessList(simulator, parcel.LocalID,
  1617. AccessList.Both, sequenceID);
  1618. // auto request dwell, will be stored in parcel tracking dictionary if enables
  1619. if (Client.Settings.ALWAYS_REQUEST_PARCEL_DWELL)
  1620. Client.Parcels.RequestDwell(simulator, parcel.LocalID);
  1621. // Fire the callback for parcel properties being received
  1622. if (m_ParcelProperties != null)
  1623. {
  1624. OnParcelProperties(new ParcelPropertiesEventArgs(simulator, parcel, result, selectedPrims, sequenceID, snapSelection));
  1625. }
  1626. // Check if all of the simulator parcels have been retrieved, if so fire another callback
  1627. if (simulator.IsParcelMapFull() && m_SimParcelsDownloaded != null)
  1628. {
  1629. OnSimParcelsDownloaded(new SimParcelsDownloadedEventArgs(simulator, simulator.Parcels, simulator.ParcelMap));
  1630. }
  1631. }
  1632. }
  1633. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1634. /// <param name="sender">The sender</param>
  1635. /// <param name="e">The EventArgs object containing the packet data</param>
  1636. /// <remarks>Raises the <see cref="ParcelAccessListReply"/> event</remarks>
  1637. protected void ParcelAccessListReplyHandler(object sender, PacketReceivedEventArgs e)
  1638. {
  1639. if (m_ParcelACL != null || Client.Settings.ALWAYS_REQUEST_PARCEL_ACL == true)
  1640. {
  1641. Packet packet = e.Packet;
  1642. Simulator simulator = e.Simulator;
  1643. ParcelAccessListReplyPacket reply = (ParcelAccessListReplyPacket)packet;
  1644. List<ParcelAccessEntry> accessList = new List<ParcelAccessEntry>(reply.List.Length);
  1645. for (int i = 0; i < reply.List.Length; i++)
  1646. {
  1647. ParcelAccessEntry pae = new ParcelAccessEntry();
  1648. pae.AgentID = reply.List[i].ID;
  1649. pae.Time = Utils.UnixTimeToDateTime((uint)reply.List[i].Time);
  1650. pae.Flags = (AccessList)reply.List[i].Flags;
  1651. accessList.Add(pae);
  1652. }
  1653. lock (simulator.Parcels.Dictionary)
  1654. {
  1655. if (simulator.Parcels.Dictionary.ContainsKey(reply.Data.LocalID))
  1656. {
  1657. Parcel parcel = simulator.Parcels.Dictionary[reply.Data.LocalID];
  1658. if ((AccessList)reply.Data.Flags == AccessList.Ban)
  1659. parcel.AccessBlackList = accessList;
  1660. else
  1661. parcel.AccessWhiteList = accessList;
  1662. simulator.Parcels.Dictionary[reply.Data.LocalID] = parcel;
  1663. }
  1664. }
  1665. if (m_ParcelACL != null)
  1666. {
  1667. OnParcelAccessListReply(new ParcelAccessListReplyEventArgs(simulator, reply.Data.SequenceID, reply.Data.LocalID,
  1668. reply.Data.Flags, accessList));
  1669. }
  1670. }
  1671. }
  1672. protected void ParcelObjectOwnersReplyHandler(string capsKey, IMessage message, Simulator simulator)
  1673. {
  1674. if (m_ParcelObjectOwnersReply != null)
  1675. {
  1676. List<ParcelPrimOwners> primOwners = new List<ParcelPrimOwners>();
  1677. ParcelObjectOwnersReplyMessage msg = (ParcelObjectOwnersReplyMessage)message;
  1678. for (int i = 0; i < msg.PrimOwnersBlock.Length; i++)
  1679. {
  1680. ParcelPrimOwners primOwner = new ParcelPrimOwners();
  1681. primOwner.OwnerID = msg.PrimOwnersBlock[i].OwnerID;
  1682. primOwner.Count = msg.PrimOwnersBlock[i].Count;
  1683. primOwner.IsGroupOwned = msg.PrimOwnersBlock[i].IsGroupOwned;
  1684. primOwner.OnlineStatus = msg.PrimOwnersBlock[i].OnlineStatus;
  1685. primOwner.NewestPrim = msg.PrimOwnersBlock[i].TimeStamp;
  1686. primOwners.Add(primOwner);
  1687. }
  1688. OnParcelObjectOwnersReply(new ParcelObjectOwnersReplyEventArgs(simulator, primOwners));
  1689. }
  1690. }
  1691. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1692. /// <param name="sender">The sender</param>
  1693. /// <param name="e">The EventArgs object containing the packet data</param>
  1694. /// <remarks>Raises the <see cref="ForceSelectObjectsReply"/> event</remarks>
  1695. protected void SelectParcelObjectsReplyHandler(object sender, PacketReceivedEventArgs e)
  1696. {
  1697. if (m_ForceSelectObjects != null)
  1698. {
  1699. Packet packet = e.Packet;
  1700. Simulator simulator = e.Simulator;
  1701. ForceObjectSelectPacket reply = (ForceObjectSelectPacket)packet;
  1702. List<uint> objectIDs = new List<uint>(reply.Data.Length);
  1703. for (int i = 0; i < reply.Data.Length; i++)
  1704. {
  1705. objectIDs.Add(reply.Data[i].LocalID);
  1706. }
  1707. OnForceSelectObjectsReply(new ForceSelectObjectsReplyEventArgs(simulator, objectIDs, reply._Header.ResetList));
  1708. }
  1709. }
  1710. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1711. /// <param name="sender">The sender</param>
  1712. /// <param name="e">The EventArgs object containing the packet data</param>
  1713. /// <remarks>Raises the <see cref="ParcelMediaUpdateReply"/> event</remarks>
  1714. protected void ParcelMediaUpdateHandler(object sender, PacketReceivedEventArgs e)
  1715. {
  1716. if (m_ParcelMediaUpdateReply != null)
  1717. {
  1718. Packet packet = e.Packet;
  1719. Simulator simulator = e.Simulator;
  1720. ParcelMediaUpdatePacket reply = (ParcelMediaUpdatePacket)packet;
  1721. ParcelMedia media = new ParcelMedia();
  1722. media.MediaAutoScale = (reply.DataBlock.MediaAutoScale == (byte)0x1) ? true : false;
  1723. media.MediaID = reply.DataBlock.MediaID;
  1724. media.MediaDesc = Utils.BytesToString(reply.DataBlockExtended.MediaDesc);
  1725. media.MediaHeight = reply.DataBlockExtended.MediaHeight;
  1726. media.MediaLoop = ((reply.DataBlockExtended.MediaLoop & 1) != 0) ? true : false;
  1727. media.MediaType = Utils.BytesToString(reply.DataBlockExtended.MediaType);
  1728. media.MediaWidth = reply.DataBlockExtended.MediaWidth;
  1729. media.MediaURL = Utils.BytesToString(reply.DataBlock.MediaURL);
  1730. OnParcelMediaUpdateReply(new ParcelMediaUpdateReplyEventArgs(simulator, media));
  1731. }
  1732. }
  1733. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1734. /// <param name="sender">The sender</param>
  1735. /// <param name="e">The EventArgs object containing the packet data</param>
  1736. protected void ParcelOverlayHandler(object sender, PacketReceivedEventArgs e)
  1737. {
  1738. const int OVERLAY_COUNT = 4;
  1739. Packet packet = e.Packet;
  1740. Simulator simulator = e.Simulator;
  1741. ParcelOverlayPacket overlay = (ParcelOverlayPacket)packet;
  1742. if (overlay.ParcelData.SequenceID >= 0 && overlay.ParcelData.SequenceID < OVERLAY_COUNT)
  1743. {
  1744. int length = overlay.ParcelData.Data.Length;
  1745. Buffer.BlockCopy(overlay.ParcelData.Data, 0, simulator.ParcelOverlay,
  1746. overlay.ParcelData.SequenceID * length, length);
  1747. simulator.ParcelOverlaysReceived++;
  1748. if (simulator.ParcelOverlaysReceived >= OVERLAY_COUNT)
  1749. {
  1750. // TODO: ParcelOverlaysReceived should become internal, and reset to zero every
  1751. // time it hits four. Also need a callback here
  1752. }
  1753. }
  1754. else
  1755. {
  1756. Logger.Log("Parcel overlay with sequence ID of " + overlay.ParcelData.SequenceID +
  1757. " received from " + simulator.ToString(), Helpers.LogLevel.Warning, Client);
  1758. }
  1759. }
  1760. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1761. /// <param name="sender">The sender</param>
  1762. /// <param name="e">The EventArgs object containing the packet data</param>
  1763. /// <remarks>Raises the <see cref="ParcelMediaCommand"/> event</remarks>
  1764. protected void ParcelMediaCommandMessagePacketHandler(object sender, PacketReceivedEventArgs e)
  1765. {
  1766. if (m_ParcelMediaCommand != null)
  1767. {
  1768. Packet packet = e.Packet;
  1769. Simulator simulator = e.Simulator;
  1770. ParcelMediaCommandMessagePacket pmc = (ParcelMediaCommandMessagePacket)packet;
  1771. ParcelMediaCommandMessagePacket.CommandBlockBlock block = pmc.CommandBlock;
  1772. OnParcelMediaCommand(new ParcelMediaCommandEventArgs(simulator, pmc.Header.Sequence, (ParcelFlags)block.Flags,
  1773. (ParcelMediaCommand)block.Command, block.Time));
  1774. }
  1775. }
  1776. #endregion Packet Handlers
  1777. }
  1778. #region EventArgs classes
  1779. /// <summary>Contains a parcels dwell data returned from the simulator in response to an <see cref="RequestParcelDwell"/></summary>
  1780. public class ParcelDwellReplyEventArgs : EventArgs
  1781. {
  1782. private readonly UUID m_ParcelID;
  1783. private readonly int m_LocalID;
  1784. private readonly float m_Dwell;
  1785. /// <summary>Get the global ID of the parcel</summary>
  1786. public UUID ParcelID { get { return m_ParcelID; } }
  1787. /// <summary>Get the simulator specific ID of the parcel</summary>
  1788. public int LocalID { get { return m_LocalID; } }
  1789. /// <summary>Get the calculated dwell</summary>
  1790. public float Dwell { get { return m_Dwell; } }
  1791. /// <summary>
  1792. /// Construct a new instance of the ParcelDwellReplyEventArgs class
  1793. /// </summary>
  1794. /// <param name="parcelID">The global ID of the parcel</param>
  1795. /// <param name="localID">The simulator specific ID of the parcel</param>
  1796. /// <param name="dwell">The calculated dwell for the parcel</param>
  1797. public ParcelDwellReplyEventArgs(UUID parcelID, int localID, float dwell)
  1798. {
  1799. this.m_ParcelID = parcelID;
  1800. this.m_LocalID = localID;
  1801. this.m_Dwell = dwell;
  1802. }
  1803. }
  1804. /// <summary>Contains basic parcel information data returned from the
  1805. /// simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
  1806. public class ParcelInfoReplyEventArgs : EventArgs
  1807. {
  1808. private readonly ParcelInfo m_Parcel;
  1809. /// <summary>Get the <see cref="ParcelInfo"/> object containing basic parcel info</summary>
  1810. public ParcelInfo Parcel { get { return m_Parcel; } }
  1811. /// <summary>
  1812. /// Construct a new instance of the ParcelInfoReplyEventArgs class
  1813. /// </summary>
  1814. /// <param name="parcel">The <see cref="ParcelInfo"/> object containing basic parcel info</param>
  1815. public ParcelInfoReplyEventArgs(ParcelInfo parcel)
  1816. {
  1817. this.m_Parcel = parcel;
  1818. }
  1819. }
  1820. /// <summary>Contains basic parcel information data returned from the simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
  1821. public class ParcelPropertiesEventArgs : EventArgs
  1822. {
  1823. private readonly Simulator m_Simulator;
  1824. private Parcel m_Parcel;
  1825. private readonly ParcelResult m_Result;
  1826. private readonly int m_SelectedPrims;
  1827. private readonly int m_SequenceID;
  1828. private readonly bool m_SnapSelection;
  1829. /// <summary>Get the simulator the parcel is located in</summary>
  1830. public Simulator Simulator { get { return m_Simulator; } }
  1831. /// <summary>Get the <see cref="Parcel"/> object containing the details</summary>
  1832. /// <remarks>If Result is NoData, this object will not contain valid data</remarks>
  1833. public Parcel Parcel { get { return m_Parcel; } }
  1834. /// <summary>Get the result of the request</summary>
  1835. public ParcelResult Result { get { return m_Result; } }
  1836. /// <summary>Get the number of primitieves your agent is
  1837. /// currently selecting and or sitting on in this parcel</summary>
  1838. public int SelectedPrims { get { return m_SelectedPrims; } }
  1839. /// <summary>Get the user assigned ID used to correlate a request with
  1840. /// these results</summary>
  1841. public int SequenceID { get { return m_SequenceID; } }
  1842. /// <summary>TODO:</summary>
  1843. public bool SnapSelection { get { return m_SnapSelection; } }
  1844. /// <summary>
  1845. /// Construct a new instance of the ParcelPropertiesEventArgs class
  1846. /// </summary>
  1847. /// <param name="simulator">The <see cref="Parcel"/> object containing the details</param>
  1848. /// <param name="parcel">The <see cref="Parcel"/> object containing the details</param>
  1849. /// <param name="result">The result of the request</param>
  1850. /// <param name="selectedPrims">The number of primitieves your agent is
  1851. /// currently selecting and or sitting on in this parcel</param>
  1852. /// <param name="sequenceID">The user assigned ID used to correlate a request with
  1853. /// these results</param>
  1854. /// <param name="snapSelection">TODO:</param>
  1855. public ParcelPropertiesEventArgs(Simulator simulator, Parcel parcel, ParcelResult result, int selectedPrims,
  1856. int sequenceID, bool snapSelection)
  1857. {
  1858. this.m_Simulator = simulator;
  1859. this.m_Parcel = parcel;
  1860. this.m_Result = result;
  1861. this.m_SelectedPrims = selectedPrims;
  1862. this.m_SequenceID = sequenceID;
  1863. this.m_SnapSelection = snapSelection;
  1864. }
  1865. }
  1866. /// <summary>Contains blacklist and whitelist data returned from the simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
  1867. public class ParcelAccessListReplyEventArgs : EventArgs
  1868. {
  1869. private readonly Simulator m_Simulator;
  1870. private readonly int m_SequenceID;
  1871. private readonly int m_LocalID;
  1872. private readonly uint m_Flags;
  1873. private readonly List<ParcelManager.ParcelAccessEntry> m_AccessList;
  1874. /// <summary>Get the simulator the parcel is located in</summary>
  1875. public Simulator Simulator { get { return m_Simulator; } }
  1876. /// <summary>Get the user assigned ID used to correlate a request with
  1877. /// these results</summary>
  1878. public int SequenceID { get { return m_SequenceID; } }
  1879. /// <summary>Get the simulator specific ID of the parcel</summary>
  1880. public int LocalID { get { return m_LocalID; } }
  1881. /// <summary>TODO:</summary>
  1882. public uint Flags { get { return m_Flags; } }
  1883. /// <summary>Get the list containing the white/blacklisted agents for the parcel</summary>
  1884. public List<ParcelManager.ParcelAccessEntry> AccessList { get { return m_AccessList; } }
  1885. /// <summary>
  1886. /// Construct a new instance of the ParcelAccessListReplyEventArgs class
  1887. /// </summary>
  1888. /// <param name="simulator">The simulator the parcel is located in</param>
  1889. /// <param name="sequenceID">The user assigned ID used to correlate a request with
  1890. /// these results</param>
  1891. /// <param name="localID">The simulator specific ID of the parcel</param>
  1892. /// <param name="flags">TODO:</param>
  1893. /// <param name="accessEntries">The list containing the white/blacklisted agents for the parcel</param>
  1894. public ParcelAccessListReplyEventArgs(Simulator simulator, int sequenceID, int localID, uint flags, List<ParcelManager.ParcelAccessEntry> accessEntries)
  1895. {
  1896. this.m_Simulator = simulator;
  1897. this.m_SequenceID = sequenceID;
  1898. this.m_LocalID = localID;
  1899. this.m_Flags = flags;
  1900. this.m_AccessList = accessEntries;
  1901. }
  1902. }
  1903. /// <summary>Contains blacklist and whitelist data returned from the
  1904. /// simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
  1905. public class ParcelObjectOwnersReplyEventArgs : EventArgs
  1906. {
  1907. private readonly Simulator m_Simulator;
  1908. private readonly List<ParcelManager.ParcelPrimOwners> m_Owners;
  1909. /// <summary>Get the simulator the parcel is located in</summary>
  1910. public Simulator Simulator { get { return m_Simulator; } }
  1911. /// <summary>Get the list containing prim ownership counts</summary>
  1912. public List<ParcelManager.ParcelPrimOwners> PrimOwners { get { return m_Owners; } }
  1913. /// <summary>
  1914. /// Construct a new instance of the ParcelObjectOwnersReplyEventArgs class
  1915. /// </summary>
  1916. /// <param name="simulator">The simulator the parcel is located in</param>
  1917. /// <param name="primOwners">The list containing prim ownership counts</param>
  1918. public ParcelObjectOwnersReplyEventArgs(Simulator simulator, List<ParcelManager.ParcelPrimOwners> primOwners)
  1919. {
  1920. this.m_Simulator = simulator;
  1921. this.m_Owners = primOwners;
  1922. }
  1923. }
  1924. /// <summary>Contains the data returned when all parcel data has been retrieved from a simulator</summary>
  1925. public class SimParcelsDownloadedEventArgs : EventArgs
  1926. {
  1927. private readonly Simulator m_Simulator;
  1928. private readonly InternalDictionary<int, Parcel> m_Parcels;
  1929. private readonly int[,] m_ParcelMap;
  1930. /// <summary>Get the simulator the parcel data was retrieved from</summary>
  1931. public Simulator Simulator { get { return m_Simulator; } }
  1932. /// <summary>A dictionary containing the parcel data where the key correlates to the ParcelMap entry</summary>
  1933. public InternalDictionary<int, Parcel> Parcels { get { return m_Parcels; } }
  1934. /// <summary>Get the multidimensional array containing a x,y grid mapped
  1935. /// to each 64x64 parcel's LocalID.</summary>
  1936. public int[,] ParcelMap { get { return m_ParcelMap; } }
  1937. /// <summary>
  1938. /// Construct a new instance of the SimParcelsDownloadedEventArgs class
  1939. /// </summary>
  1940. /// <param name="simulator">The simulator the parcel data was retrieved from</param>
  1941. /// <param name="simParcels">The dictionary containing the parcel data</param>
  1942. /// <param name="parcelMap">The multidimensional array containing a x,y grid mapped
  1943. /// to each 64x64 parcel's LocalID.</param>
  1944. public SimParcelsDownloadedEventArgs(Simulator simulator, InternalDictionary<int, Parcel> simParcels, int[,] parcelMap)
  1945. {
  1946. this.m_Simulator = simulator;
  1947. this.m_Parcels = simParcels;
  1948. this.m_ParcelMap = parcelMap;
  1949. }
  1950. }
  1951. /// <summary>Contains the data returned when a <see cref="RequestForceSelectObjects"/> request</summary>
  1952. public class ForceSelectObjectsReplyEventArgs : EventArgs
  1953. {
  1954. private readonly Simulator m_Simulator;
  1955. private readonly List<uint> m_ObjectIDs;
  1956. private readonly bool m_ResetList;
  1957. /// <summary>Get the simulator the parcel data was retrieved from</summary>
  1958. public Simulator Simulator { get { return m_Simulator; } }
  1959. /// <summary>Get the list of primitive IDs</summary>
  1960. public List<uint> ObjectIDs { get { return m_ObjectIDs; } }
  1961. /// <summary>true if the list is clean and contains the information
  1962. /// only for a given request</summary>
  1963. public bool ResetList { get { return m_ResetList; } }
  1964. /// <summary>
  1965. /// Construct a new instance of the ForceSelectObjectsReplyEventArgs class
  1966. /// </summary>
  1967. /// <param name="simulator">The simulator the parcel data was retrieved from</param>
  1968. /// <param name="objectIDs">The list of primitive IDs</param>
  1969. /// <param name="resetList">true if the list is clean and contains the information
  1970. /// only for a given request</param>
  1971. public ForceSelectObjectsReplyEventArgs(Simulator simulator, List<uint> objectIDs, bool resetList)
  1972. {
  1973. this.m_Simulator = simulator;
  1974. this.m_ObjectIDs = objectIDs;
  1975. this.m_ResetList = resetList;
  1976. }
  1977. }
  1978. /// <summary>Contains data when the media data for a parcel the avatar is on changes</summary>
  1979. public class ParcelMediaUpdateReplyEventArgs : EventArgs
  1980. {
  1981. private readonly Simulator m_Simulator;
  1982. private readonly ParcelMedia m_ParcelMedia;
  1983. /// <summary>Get the simulator the parcel media data was updated in</summary>
  1984. public Simulator Simulator { get { return m_Simulator; } }
  1985. /// <summary>Get the updated media information</summary>
  1986. public ParcelMedia Media { get { return m_ParcelMedia; } }
  1987. /// <summary>
  1988. /// Construct a new instance of the ParcelMediaUpdateReplyEventArgs class
  1989. /// </summary>
  1990. /// <param name="simulator">the simulator the parcel media data was updated in</param>
  1991. /// <param name="media">The updated media information</param>
  1992. public ParcelMediaUpdateReplyEventArgs(Simulator simulator, ParcelMedia media)
  1993. {
  1994. this.m_Simulator = simulator;
  1995. this.m_ParcelMedia = media;
  1996. }
  1997. }
  1998. /// <summary>Contains the media command for a parcel the agent is currently on</summary>
  1999. public class ParcelMediaCommandEventArgs : EventArgs
  2000. {
  2001. private readonly Simulator m_Simulator;
  2002. private readonly uint m_Sequence;
  2003. private readonly ParcelFlags m_ParcelFlags;
  2004. private readonly ParcelMediaCommand m_MediaCommand;
  2005. private readonly float m_Time;
  2006. /// <summary>Get the simulator the parcel media command was issued in</summary>
  2007. public Simulator Simulator { get { return m_Simulator; } }
  2008. /// <summary></summary>
  2009. public uint Sequence { get { return m_Sequence; } }
  2010. /// <summary></summary>
  2011. public ParcelFlags ParcelFlags { get { return m_ParcelFlags; } }
  2012. /// <summary>Get the media command that was sent</summary>
  2013. public ParcelMediaCommand MediaCommand { get { return m_MediaCommand; } }
  2014. /// <summary></summary>
  2015. public float Time { get { return m_Time; } }
  2016. /// <summary>
  2017. /// Construct a new instance of the ParcelMediaCommandEventArgs class
  2018. /// </summary>
  2019. /// <param name="simulator">The simulator the parcel media command was issued in</param>
  2020. /// <param name="sequence"></param>
  2021. /// <param name="flags"></param>
  2022. /// <param name="command">The media command that was sent</param>
  2023. /// <param name="time"></param>
  2024. public ParcelMediaCommandEventArgs(Simulator simulator, uint sequence, ParcelFlags flags, ParcelMediaCommand command, float time)
  2025. {
  2026. this.m_Simulator = simulator;
  2027. this.m_Sequence = sequence;
  2028. this.m_ParcelFlags = flags;
  2029. this.m_MediaCommand = command;
  2030. this.m_Time = time;
  2031. }
  2032. }
  2033. #endregion
  2034. }