2006-10-21 02:52:28 +00:00
/ *
2015-11-06 19:40:28 +01:00
* Copyright ( c ) 2006 - 2016 , openmetaverse . co
2022-01-02 09:04:28 -06:00
* Copyright ( c ) 2021 - 2022 , Sjofn LLC
2006-10-21 02:52:28 +00:00
* All rights reserved .
*
2009-04-13 09:32:25 +00:00
* - Redistribution and use in source and binary forms , with or without
2006-10-21 02:52:28 +00:00
* modification , are permitted provided that the following conditions are met :
*
* - Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
2015-11-06 19:00:05 +01:00
* - Neither the name of the openmetaverse . co nor the names
2006-10-21 02:52:28 +00:00
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
2009-04-13 09:32:25 +00:00
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
2006-10-21 02:52:28 +00:00
* POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
2007-11-06 09:26:10 +00:00
using System.Threading ;
2008-03-06 21:28:52 +00:00
using System.Reflection ;
2009-10-16 07:23:18 +00:00
using System.Collections.Generic ;
2016-09-25 19:52:04 -05:00
using System.Linq ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.Packets ;
2009-10-16 07:23:18 +00:00
using OpenMetaverse.Interfaces ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.StructuredData ;
2009-04-10 21:34:59 +00:00
using OpenMetaverse.Messages.Linden ;
2022-11-03 14:19:56 -05:00
using System.Threading.Tasks ;
2022-11-04 07:13:09 -05:00
using LibreMetaverse ;
2006-10-21 02:52:28 +00:00
2008-07-21 21:12:59 +00:00
namespace OpenMetaverse
2006-10-21 02:52:28 +00:00
{
2008-09-22 13:02:27 +00:00
#region Enums
/// <summary>
/// Type of return to use when returning objects from a parcel
/// </summary>
public enum ObjectReturnType : uint
{
/// <summary></summary>
None = 0 ,
/// <summary>Return objects owned by parcel owner</summary>
Owner = 1 < < 1 ,
/// <summary>Return objects set to group</summary>
Group = 1 < < 2 ,
/// <summary>Return objects not owned by parcel owner or set to group</summary>
Other = 1 < < 3 ,
/// <summary>Return a specific list of objects on parcel</summary>
List = 1 < < 4 ,
/// <summary>Return objects that are marked for-sale</summary>
Sell = 1 < < 5
}
/// <summary>
/// Blacklist/Whitelist flags used in parcels Access List
/// </summary>
public enum ParcelAccessFlags : uint
{
/// <summary>Agent is denied access</summary>
NoAccess = 0 ,
/// <summary>Agent is granted access</summary>
Access = 1
}
/// <summary>
/// The result of a request for parcel properties
/// </summary>
public enum ParcelResult : int
{
/// <summary>No matches were found for the request</summary>
NoData = - 1 ,
/// <summary>Request matched a single parcel</summary>
Single = 0 ,
/// <summary>Request matched multiple parcels</summary>
Multiple = 1
}
/// <summary>
/// Flags used in the ParcelAccessListRequest packet to specify whether
/// we want the access list (whitelist), ban list (blacklist), or both
/// </summary>
[Flags]
public enum AccessList : uint
{
/// <summary>Request the access list</summary>
Access = 1 < < 0 ,
/// <summary>Request the ban list</summary>
Ban = 1 < < 1 ,
2008-10-18 23:53:30 +00:00
/// <summary>Request both White and Black lists</summary>
2008-09-22 13:02:27 +00:00
Both = Access | Ban
}
/// <summary>
/// Sequence ID in ParcelPropertiesReply packets (sent when avatar
/// tries to cross a parcel border)
/// </summary>
2009-04-09 01:17:40 +00:00
public enum ParcelPropertiesStatus : int
2008-09-22 13:02:27 +00:00
{
/// <summary>Parcel is currently selected</summary>
ParcelSelected = - 10000 ,
/// <summary>Parcel restricted to a group the avatar is not a
/// member of</summary>
CollisionNotInGroup = - 20000 ,
/// <summary>Avatar is banned from the parcel</summary>
CollisionBanned = - 30000 ,
/// <summary>Parcel is restricted to an access list that the
/// avatar is not on</summary>
CollisionNotOnAccessList = - 40000 ,
/// <summary>Response to hovering over a parcel</summary>
HoveredOverParcel = - 50000
}
/// <summary>
2009-10-07 20:13:33 +00:00
/// The tool to use when modifying terrain levels
2008-09-22 13:02:27 +00:00
/// </summary>
public enum TerraformAction : byte
{
2009-10-07 20:13:33 +00:00
/// <summary>Level the terrain</summary>
2008-09-22 13:02:27 +00:00
Level = 0 ,
2009-10-07 20:13:33 +00:00
/// <summary>Raise the terrain</summary>
2008-09-22 13:02:27 +00:00
Raise = 1 ,
2009-10-07 20:13:33 +00:00
/// <summary>Lower the terrain</summary>
2008-09-22 13:02:27 +00:00
Lower = 2 ,
2009-10-07 20:13:33 +00:00
/// <summary>Smooth the terrain</summary>
2008-09-22 13:02:27 +00:00
Smooth = 3 ,
2009-10-07 20:13:33 +00:00
/// <summary>Add random noise to the terrain</summary>
2008-09-22 13:02:27 +00:00
Noise = 4 ,
2009-10-07 20:13:33 +00:00
/// <summary>Revert terrain to simulator default</summary>
2008-09-22 13:02:27 +00:00
Revert = 5
}
/// <summary>
2009-10-07 20:13:33 +00:00
/// The tool size to use when changing terrain levels
2008-09-22 13:02:27 +00:00
/// </summary>
public enum TerraformBrushSize : byte
{
2009-10-07 20:13:33 +00:00
/// <summary>Small</summary>
2008-09-22 13:02:27 +00:00
Small = 1 ,
2009-10-07 20:13:33 +00:00
/// <summary>Medium</summary>
2008-09-22 13:02:27 +00:00
Medium = 2 ,
2009-10-07 20:13:33 +00:00
/// <summary>Large</summary>
2008-09-22 13:02:27 +00:00
Large = 4
}
/// <summary>
/// Reasons agent is denied access to a parcel on the simulator
/// </summary>
public enum AccessDeniedReason : byte
{
/// <summary>Agent is not denied, access is granted</summary>
NotDenied = 0 ,
/// <summary>Agent is not a member of the group set for the parcel, or which owns the parcel</summary>
NotInGroup = 1 ,
/// <summary>Agent is not on the parcels specific allow list</summary>
NotOnAllowList = 2 ,
/// <summary>Agent is on the parcels ban list</summary>
BannedFromParcel = 3 ,
/// <summary>Unknown</summary>
NoAccess = 4 ,
/// <summary>Agent is not age verified and parcel settings deny access to non age verified avatars</summary>
NotAgeVerified = 5
}
/// <summary>
/// Parcel overlay type. This is used primarily for highlighting and
/// coloring which is why it is a single integer instead of a set of
/// flags
/// </summary>
2008-09-22 15:05:14 +00:00
/// <remarks>These values seem to be poorly thought out. The first three
/// bits represent a single value, not flags. For example Auction (0x05) is
/// not a combination of OwnedByOther (0x01) and ForSale(0x04). However,
/// the BorderWest and BorderSouth values are bit flags that get attached
/// to the value stored in the first three bits. Bits four, five, and six
/// are unused</remarks>
2009-10-07 20:13:33 +00:00
[Flags]
2008-09-22 13:02:27 +00:00
public enum ParcelOverlayType : byte
{
/// <summary>Public land</summary>
Public = 0 ,
/// <summary>Land is owned by another avatar</summary>
OwnedByOther = 1 ,
/// <summary>Land is owned by a group</summary>
OwnedByGroup = 2 ,
/// <summary>Land is owned by the current avatar</summary>
OwnedBySelf = 3 ,
/// <summary>Land is for sale</summary>
ForSale = 4 ,
/// <summary>Land is being auctioned</summary>
Auction = 5 ,
2011-07-12 23:15:58 +00:00
/// <summary>Land is private</summary>
Private = 32 ,
2008-09-22 13:02:27 +00:00
/// <summary>To the west of this area is a parcel border</summary>
BorderWest = 64 ,
/// <summary>To the south of this area is a parcel border</summary>
BorderSouth = 128
}
2009-04-09 01:17:40 +00:00
/// <summary>
/// Various parcel properties
/// </summary>
[Flags]
public enum ParcelFlags : uint
{
/// <summary>No flags set</summary>
None = 0 ,
/// <summary>Allow avatars to fly (a client-side only restriction)</summary>
AllowFly = 1 < < 0 ,
/// <summary>Allow foreign scripts to run</summary>
AllowOtherScripts = 1 < < 1 ,
/// <summary>This parcel is for sale</summary>
ForSale = 1 < < 2 ,
/// <summary>Allow avatars to create a landmark on this parcel</summary>
AllowLandmark = 1 < < 3 ,
/// <summary>Allows all avatars to edit the terrain on this parcel</summary>
AllowTerraform = 1 < < 4 ,
/// <summary>Avatars have health and can take damage on this parcel.
/// If set, avatars can be killed and sent home here</summary>
AllowDamage = 1 < < 5 ,
/// <summary>Foreign avatars can create objects here</summary>
CreateObjects = 1 < < 6 ,
/// <summary>All objects on this parcel can be purchased</summary>
ForSaleObjects = 1 < < 7 ,
/// <summary>Access is restricted to a group</summary>
UseAccessGroup = 1 < < 8 ,
/// <summary>Access is restricted to a whitelist</summary>
UseAccessList = 1 < < 9 ,
/// <summary>Ban blacklist is enabled</summary>
UseBanList = 1 < < 10 ,
/// <summary>Unknown</summary>
UsePassList = 1 < < 11 ,
/// <summary>List this parcel in the search directory</summary>
ShowDirectory = 1 < < 12 ,
/// <summary>Allow personally owned parcels to be deeded to group</summary>
AllowDeedToGroup = 1 < < 13 ,
/// <summary>If Deeded, owner contributes required tier to group parcel is deeded to</summary>
ContributeWithDeed = 1 < < 14 ,
/// <summary>Restrict sounds originating on this parcel to the
/// parcel boundaries</summary>
SoundLocal = 1 < < 15 ,
/// <summary>Objects on this parcel are sold when the land is
/// purchsaed</summary>
SellParcelObjects = 1 < < 16 ,
/// <summary>Allow this parcel to be published on the web</summary>
AllowPublish = 1 < < 17 ,
/// <summary>The information for this parcel is mature content</summary>
MaturePublish = 1 < < 18 ,
/// <summary>The media URL is an HTML page</summary>
UrlWebPage = 1 < < 19 ,
/// <summary>The media URL is a raw HTML string</summary>
UrlRawHtml = 1 < < 20 ,
/// <summary>Restrict foreign object pushes</summary>
RestrictPushObject = 1 < < 21 ,
/// <summary>Ban all non identified/transacted avatars</summary>
DenyAnonymous = 1 < < 22 ,
// <summary>Ban all identified avatars [OBSOLETE]</summary>
//[Obsolete]
2010-02-12 21:59:13 +00:00
// This was obsoleted in 1.19.0 but appears to be recycled and is used on linden homes parcels
LindenHome = 1 < < 23 ,
2009-04-09 01:17:40 +00:00
// <summary>Ban all transacted avatars [OBSOLETE]</summary>
//[Obsolete]
//DenyTransacted = 1 << 24,
/// <summary>Allow group-owned scripts to run</summary>
AllowGroupScripts = 1 < < 25 ,
/// <summary>Allow object creation by group members or group
/// objects</summary>
CreateGroupObjects = 1 < < 26 ,
/// <summary>Allow all objects to enter this parcel</summary>
AllowAPrimitiveEntry = 1 < < 27 ,
/// <summary>Only allow group and owner objects to enter this parcel</summary>
AllowGroupObjectEntry = 1 < < 28 ,
/// <summary>Voice Enabled on this parcel</summary>
AllowVoiceChat = 1 < < 29 ,
/// <summary>Use Estate Voice channel for Voice on this parcel</summary>
UseEstateVoiceChan = 1 < < 30 ,
/// <summary>Deny Age Unverified Users</summary>
DenyAgeUnverified = 1 U < < 31
}
/// <summary>
/// Parcel ownership status
/// </summary>
public enum ParcelStatus : sbyte
{
/// <summary>Placeholder</summary>
None = - 1 ,
/// <summary>Parcel is leased (owned) by an avatar or group</summary>
Leased = 0 ,
/// <summary>Parcel is in process of being leased (purchased) by an avatar or group</summary>
LeasePending = 1 ,
/// <summary>Parcel has been abandoned back to Governor Linden</summary>
Abandoned = 2
}
/// <summary>
/// Category parcel is listed in under search
/// </summary>
public enum ParcelCategory : sbyte
{
/// <summary>No assigned category</summary>
None = 0 ,
/// <summary>Linden Infohub or public area</summary>
Linden ,
/// <summary>Adult themed area</summary>
Adult ,
/// <summary>Arts and Culture</summary>
Arts ,
/// <summary>Business</summary>
Business ,
/// <summary>Educational</summary>
Educational ,
/// <summary>Gaming</summary>
Gaming ,
/// <summary>Hangout or Club</summary>
Hangout ,
/// <summary>Newcomer friendly</summary>
Newcomer ,
/// <summary>Parks and Nature</summary>
Park ,
/// <summary>Residential</summary>
Residential ,
/// <summary>Shopping</summary>
Shopping ,
/// <summary>Not Used?</summary>
Stage ,
/// <summary>Other</summary>
Other ,
/// <summary>Not an actual category, only used for queries</summary>
Any = - 1
}
/// <summary>
/// Type of teleport landing for a parcel
/// </summary>
public enum LandingType : byte
{
/// <summary>Unset, simulator default</summary>
None = 0 ,
/// <summary>Specific landing point set for this parcel</summary>
LandingPoint = 1 ,
/// <summary>No landing point set, direct teleports enabled for
/// this parcel</summary>
Direct = 2
}
2009-07-10 01:48:42 +00:00
/// <summary>
/// Parcel Media Command used in ParcelMediaCommandMessage
/// </summary>
public enum ParcelMediaCommand : uint
{
/// <summary>Stop the media stream and go back to the first frame</summary>
Stop = 0 ,
/// <summary>Pause the media stream (stop playing but stay on current frame)</summary>
Pause ,
/// <summary>Start the current media stream playing and stop when the end is reached</summary>
Play ,
/// <summary>Start the current media stream playing,
/// loop to the beginning when the end is reached and continue to play</summary>
Loop ,
/// <summary>Specifies the texture to replace with video</summary>
/// <remarks>If passing the key of a texture, it must be explicitly typecast as a key,
/// not just passed within double quotes.</remarks>
Texture ,
/// <summary>Specifies the movie URL (254 characters max)</summary>
URL ,
/// <summary>Specifies the time index at which to begin playing</summary>
Time ,
/// <summary>Specifies a single agent to apply the media command to</summary>
Agent ,
/// <summary>Unloads the stream. While the stop command sets the texture to the first frame of the movie,
/// unload resets it to the real texture that the movie was replacing.</summary>
Unload ,
/// <summary>Turn on/off the auto align feature, similar to the auto align checkbox in the parcel media properties
/// (NOT to be confused with the "align" function in the textures view of the editor!) Takes TRUE or FALSE as parameter.</summary>
AutoAlign ,
/// <summary>Allows a Web page or image to be placed on a prim (1.19.1 RC0 and later only).
/// Use "text/html" for HTML.</summary>
Type ,
/// <summary>Resizes a Web page to fit on x, y pixels (1.19.1 RC0 and later only).</summary>
/// <remarks>This might still not be working</remarks>
Size ,
/// <summary>Sets a description for the media being displayed (1.19.1 RC0 and later only).</summary>
Desc
}
2008-09-22 13:02:27 +00:00
#endregion Enums
2007-04-11 04:46:25 +00:00
#region Structs
/// <summary>
2008-05-01 10:48:09 +00:00
/// Some information about a parcel of land returned from a DirectoryManager search
2007-04-11 04:46:25 +00:00
/// </summary>
public struct ParcelInfo
{
2008-05-01 10:48:09 +00:00
/// <summary>Global Key of record</summary>
2008-07-25 05:15:05 +00:00
public UUID ID ;
2008-07-26 08:50:37 +00:00
/// <summary>Parcel Owners <seealso cref="UUID"/></summary>
2008-07-25 05:15:05 +00:00
public UUID OwnerID ;
2008-05-01 10:48:09 +00:00
/// <summary>Name field of parcel, limited to 128 characters</summary>
2007-04-11 04:46:25 +00:00
public string Name ;
2008-05-01 10:48:09 +00:00
/// <summary>Description field of parcel, limited to 256 characters</summary>
2007-04-11 04:46:25 +00:00
public string Description ;
2008-05-01 10:48:09 +00:00
/// <summary>Total Square meters of parcel</summary>
2007-04-11 04:46:25 +00:00
public int ActualArea ;
2008-05-01 10:48:09 +00:00
/// <summary>Total area billable as Tier, for group owned land this will be 10% less than ActualArea</summary>
2007-04-11 04:46:25 +00:00
public int BillableArea ;
2008-05-01 10:48:09 +00:00
/// <summary>True of parcel is in Mature simulator</summary>
2007-04-11 04:46:25 +00:00
public bool Mature ;
2008-05-01 10:48:09 +00:00
/// <summary>Grid global X position of parcel</summary>
2007-04-11 04:46:25 +00:00
public float GlobalX ;
2008-05-01 10:48:09 +00:00
/// <summary>Grid global Y position of parcel</summary>
2007-04-11 04:46:25 +00:00
public float GlobalY ;
2008-05-01 10:48:09 +00:00
/// <summary>Grid global Z position of parcel (not used)</summary>
2007-04-11 04:46:25 +00:00
public float GlobalZ ;
2008-05-01 10:48:09 +00:00
/// <summary>Name of simulator parcel is located in</summary>
2007-04-11 04:46:25 +00:00
public string SimName ;
2008-07-28 22:23:48 +00:00
/// <summary>Texture <seealso cref="T:OpenMetaverse.UUID"/> of parcels display picture</summary>
2008-07-25 05:15:05 +00:00
public UUID SnapshotID ;
2008-05-01 10:48:09 +00:00
/// <summary>Float representing calculated traffic based on time spent on parcel by avatars</summary>
2007-04-11 04:46:25 +00:00
public float Dwell ;
2008-05-01 10:48:09 +00:00
/// <summary>Sale price of parcel (not used)</summary>
2007-04-11 04:46:25 +00:00
public int SalePrice ;
2008-05-01 10:48:09 +00:00
/// <summary>Auction ID of parcel</summary>
2007-04-11 04:46:25 +00:00
public int AuctionID ;
}
2008-07-26 08:50:37 +00:00
/// <summary>
/// Parcel Media Information
/// </summary>
public struct ParcelMedia
{
/// <summary>A byte, if 0x1 viewer should auto scale media to fit object</summary>
2009-04-10 21:34:59 +00:00
public bool MediaAutoScale ;
2008-07-26 08:50:37 +00:00
/// <summary>A boolean, if true the viewer should loop the media</summary>
public bool MediaLoop ;
/// <summary>The Asset UUID of the Texture which when applied to a
/// primitive will display the media</summary>
public UUID MediaID ;
/// <summary>A URL which points to any Quicktime supported media type</summary>
2009-04-14 05:32:20 +00:00
public string MediaURL ;
2008-07-26 08:50:37 +00:00
/// <summary>A description of the media</summary>
public string MediaDesc ;
/// <summary>An Integer which represents the height of the media</summary>
public int MediaHeight ;
/// <summary>An integer which represents the width of the media</summary>
public int MediaWidth ;
/// <summary>A string which contains the mime type of the media</summary>
public string MediaType ;
}
2008-09-22 08:49:34 +00:00
2007-04-11 04:46:25 +00:00
#endregion Structs
#region Parcel Class
2006-10-21 02:52:28 +00:00
/// <summary>
2007-03-19 13:38:10 +00:00
/// Parcel of land, a portion of virtual real estate in a simulator
2006-10-21 02:52:28 +00:00
/// </summary>
2010-04-21 00:00:54 +00:00
public class Parcel
2006-10-21 02:52:28 +00:00
{
2009-11-30 22:49:35 +00:00
/// <summary>The total number of contiguous 4x4 meter blocks your agent owns within this parcel</summary>
2006-10-21 02:52:28 +00:00
public int SelfCount ;
2009-11-30 23:09:25 +00:00
/// <summary>The total number of contiguous 4x4 meter blocks contained in this parcel owned by a group or agent other than your own</summary>
2006-10-21 02:52:28 +00:00
public int OtherCount ;
2009-11-30 22:49:35 +00:00
/// <summary>Deprecated, Value appears to always be 0</summary>
2006-10-21 02:52:28 +00:00
public int PublicCount ;
2007-03-19 13:38:10 +00:00
/// <summary>Simulator-local ID of this parcel</summary>
2007-11-29 19:38:32 +00:00
public int LocalID ;
2007-03-19 13:38:10 +00:00
/// <summary>UUID of the owner of this parcel</summary>
2008-07-25 05:15:05 +00:00
public UUID OwnerID ;
2007-03-19 13:38:10 +00:00
/// <summary>Whether the land is deeded to a group or not</summary>
2006-10-21 02:52:28 +00:00
public bool IsGroupOwned ;
/// <summary></summary>
public uint AuctionID ;
2006-12-16 03:24:05 +00:00
/// <summary>Date land was claimed</summary>
2007-03-19 13:38:10 +00:00
public DateTime ClaimDate ;
2007-03-26 23:12:39 +00:00
/// <summary>Appears to always be zero</summary>
2006-10-21 02:52:28 +00:00
public int ClaimPrice ;
2008-07-26 08:50:37 +00:00
/// <summary>This field is no longer used</summary>
2006-10-21 02:52:28 +00:00
public int RentPrice ;
2007-03-19 13:38:10 +00:00
/// <summary>Minimum corner of the axis-aligned bounding box for this
/// parcel</summary>
2008-07-25 05:15:05 +00:00
public Vector3 AABBMin ;
2007-03-19 13:38:10 +00:00
/// <summary>Maximum corner of the axis-aligned bounding box for this
/// parcel</summary>
2008-07-25 05:15:05 +00:00
public Vector3 AABBMax ;
2007-03-26 23:12:39 +00:00
/// <summary>Bitmap describing land layout in 4x4m squares across the
/// entire region</summary>
2006-10-21 02:52:28 +00:00
public byte [ ] Bitmap ;
2007-03-19 14:38:01 +00:00
/// <summary>Total parcel land area</summary>
2006-10-21 02:52:28 +00:00
public int Area ;
/// <summary></summary>
2007-03-19 13:38:10 +00:00
public ParcelStatus Status ;
2009-11-30 22:49:35 +00:00
/// <summary>Maximum primitives across the entire simulator owned by the same agent or group that owns this parcel that can be used</summary>
2007-03-19 13:38:10 +00:00
public int SimWideMaxPrims ;
2009-11-30 22:49:35 +00:00
/// <summary>Total primitives across the entire simulator calculated by combining the allowed prim counts for each parcel
/// owned by the agent or group that owns this parcel</summary>
2007-03-19 13:38:10 +00:00
public int SimWideTotalPrims ;
/// <summary>Maximum number of primitives this parcel supports</summary>
public int MaxPrims ;
/// <summary>Total number of primitives on this parcel</summary>
public int TotalPrims ;
2009-11-30 23:09:25 +00:00
/// <summary>For group-owned parcels this indicates the total number of prims deeded to the group,
/// for parcels owned by an individual this inicates the number of prims owned by the individual</summary>
2007-03-19 13:38:10 +00:00
public int OwnerPrims ;
2007-03-26 23:12:39 +00:00
/// <summary>Total number of primitives owned by the parcel group on
2009-11-30 22:49:35 +00:00
/// this parcel, or for parcels owned by an individual with a group set the
/// total number of prims set to that group.</summary>
2007-03-19 13:38:10 +00:00
public int GroupPrims ;
2009-11-30 22:49:35 +00:00
/// <summary>Total number of prims owned by other avatars that are not set to group, or not the parcel owner</summary>
2007-03-19 13:38:10 +00:00
public int OtherPrims ;
2009-11-30 22:49:35 +00:00
/// <summary>A bonus multiplier which allows parcel prim counts to go over times this amount, this does not affect
/// the max prims per simulator. e.g: 117 prim parcel limit x 1.5 bonus = 175 allowed</summary>
2007-03-19 13:38:10 +00:00
public float ParcelPrimBonus ;
2007-04-11 04:46:25 +00:00
/// <summary>Autoreturn value in minutes for others' objects</summary>
2006-10-21 02:52:28 +00:00
public int OtherCleanTime ;
/// <summary></summary>
2007-02-12 11:15:49 +00:00
public ParcelFlags Flags ;
2007-04-11 04:46:25 +00:00
/// <summary>Sale price of the parcel, only useful if ForSale is set</summary>
/// <remarks>The SalePrice will remain the same after an ownership
/// transfer (sale), so it can be used to see the purchase price after
/// a sale if the new owner has not changed it</remarks>
2006-10-21 02:52:28 +00:00
public int SalePrice ;
2006-12-16 03:24:05 +00:00
/// <summary>Parcel Name</summary>
2006-10-21 02:52:28 +00:00
public string Name ;
2006-12-16 03:24:05 +00:00
/// <summary>Parcel Description</summary>
2006-10-21 02:52:28 +00:00
public string Desc ;
2006-12-16 03:24:05 +00:00
/// <summary>URL For Music Stream</summary>
2009-04-14 05:32:20 +00:00
public string MusicURL ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
2008-07-25 05:15:05 +00:00
public UUID GroupID ;
2006-12-16 03:24:05 +00:00
/// <summary>Price for a temporary pass</summary>
2006-10-21 02:52:28 +00:00
public int PassPrice ;
2006-12-16 03:24:05 +00:00
/// <summary>How long is pass valid for</summary>
2006-10-21 02:52:28 +00:00
public float PassHours ;
/// <summary></summary>
2007-03-23 16:11:01 +00:00
public ParcelCategory Category ;
2006-12-16 03:24:05 +00:00
/// <summary>Key of authorized buyer</summary>
2008-07-25 05:15:05 +00:00
public UUID AuthBuyerID ;
2006-12-16 03:24:05 +00:00
/// <summary>Key of parcel snapshot</summary>
2008-07-25 05:15:05 +00:00
public UUID SnapshotID ;
2009-11-30 22:49:35 +00:00
/// <summary>The landing point location</summary>
2008-07-25 05:15:05 +00:00
public Vector3 UserLocation ;
2009-11-30 22:49:35 +00:00
/// <summary>The landing point LookAt</summary>
2008-07-25 05:15:05 +00:00
public Vector3 UserLookAt ;
2009-11-30 22:49:35 +00:00
/// <summary>The type of landing enforced from the <see cref="LandingType"/> enum</summary>
2008-09-22 08:49:34 +00:00
public LandingType Landing ;
2022-11-03 14:19:56 -05:00
/// <summary>Traffic count</summary>
2006-10-21 02:52:28 +00:00
public float Dwell ;
2007-01-19 13:15:12 +00:00
/// <summary></summary>
2007-03-19 13:38:10 +00:00
public bool RegionDenyAnonymous ;
/// <summary></summary>
public bool RegionPushOverride ;
2008-10-18 23:53:30 +00:00
/// <summary>Access list of who is whitelisted on this
2007-04-17 20:48:18 +00:00
/// parcel</summary>
2008-10-18 23:53:30 +00:00
public List < ParcelManager . ParcelAccessEntry > AccessWhiteList ;
/// <summary>Access list of who is blacklisted on this
/// parcel</summary>
public List < ParcelManager . ParcelAccessEntry > AccessBlackList ;
2008-03-10 09:19:51 +00:00
/// <summary>TRUE of region denies access to age unverified users</summary>
2008-03-06 21:28:52 +00:00
public bool RegionDenyAgeUnverified ;
2008-03-10 09:19:51 +00:00
/// <summary>true to obscure (hide) media url</summary>
public bool ObscureMedia ;
/// <summary>true to obscure (hide) music url</summary>
public bool ObscureMusic ;
2008-07-26 08:50:37 +00:00
/// <summary>A struct containing media details</summary>
public ParcelMedia Media ;
2021-06-26 21:24:16 -05:00
/// <summary>Parcel privacy see avatars outside/inside parcel</summary>
public bool SeeAVs ;
/// <summary>Parcel privacy play sounds attached to avatars outside/inside parcel</summary>
public bool AnyAVSounds ;
/// <summary>Parcel privacy play sounds for group members</summary>
public bool GroupAVSounds ;
2007-04-17 10:17:21 +00:00
2008-05-01 10:48:09 +00:00
/// <summary>
/// Displays a parcel object in string format
/// </summary>
/// <returns>string containing key=value pairs of a parcel object</returns>
2008-03-06 21:28:52 +00:00
public override string ToString ( )
{
Type parcelType = this . GetType ( ) ;
FieldInfo [ ] fields = parcelType . GetFields ( ) ;
2016-09-25 19:52:04 -05:00
return fields . Aggregate ( "" , ( current , field ) = > current + ( field . Name + " = " + field . GetValue ( this ) + " " ) ) ;
2008-03-06 21:28:52 +00:00
}
2006-10-21 02:52:28 +00:00
/// <summary>
2022-11-03 14:19:56 -05:00
/// Default constructor
2006-10-21 02:52:28 +00:00
/// </summary>
2007-03-19 13:38:10 +00:00
/// <param name="localID">Local ID of this parcel</param>
2008-09-22 13:02:27 +00:00
public Parcel ( int localID )
2006-10-21 02:52:28 +00:00
{
2007-11-29 19:38:32 +00:00
LocalID = localID ;
2008-08-12 22:38:02 +00:00
ClaimDate = Utils . Epoch ;
2009-03-06 01:32:02 +00:00
Bitmap = Utils . EmptyBytes ;
2022-11-03 14:19:56 -05:00
Name = string . Empty ;
Desc = string . Empty ;
MusicURL = string . Empty ;
2010-04-21 00:00:54 +00:00
AccessWhiteList = new List < ParcelManager . ParcelAccessEntry > ( 0 ) ;
2008-10-18 23:53:30 +00:00
AccessBlackList = new List < ParcelManager . ParcelAccessEntry > ( 0 ) ;
2008-07-26 08:50:37 +00:00
Media = new ParcelMedia ( ) ;
2006-10-21 02:52:28 +00:00
}
/// <summary>
2007-03-19 13:38:10 +00:00
/// Update the simulator with any local changes to this Parcel object
2006-10-21 02:52:28 +00:00
/// </summary>
2022-11-03 14:19:56 -05:00
/// <param name="client">Client message originates from</param>
2008-09-22 13:02:27 +00:00
/// <param name="simulator">Simulator to send updates to</param>
2007-04-11 04:46:25 +00:00
/// <param name="wantReply">Whether we want the simulator to confirm
/// the update with a reply packet or not</param>
2022-11-03 14:19:56 -05:00
public void Update ( GridClient client , Simulator simulator , bool wantReply )
2006-10-21 02:52:28 +00:00
{
2022-11-03 14:19:56 -05:00
Uri cap = simulator . Caps . CapabilityURI ( "ParcelPropertiesUpdate" ) ;
if ( cap ! = null )
2009-01-27 23:06:31 +00:00
{
2022-11-04 07:13:09 -05:00
ParcelPropertiesUpdateMessage payload = new ParcelPropertiesUpdateMessage
2016-09-25 19:52:04 -05:00
{
AuthBuyerID = AuthBuyerID ,
Category = Category ,
Desc = Desc ,
GroupID = GroupID ,
Landing = Landing ,
LocalID = LocalID ,
MediaAutoScale = Media . MediaAutoScale ,
MediaDesc = Media . MediaDesc ,
MediaHeight = Media . MediaHeight ,
MediaID = Media . MediaID ,
MediaLoop = Media . MediaLoop ,
MediaType = Media . MediaType ,
MediaURL = Media . MediaURL ,
MediaWidth = Media . MediaWidth ,
MusicURL = MusicURL ,
Name = Name ,
ObscureMedia = ObscureMedia ,
ObscureMusic = ObscureMusic ,
ParcelFlags = Flags ,
PassHours = PassHours ,
PassPrice = ( uint ) PassPrice ,
SalePrice = ( uint ) SalePrice ,
SnapshotID = SnapshotID ,
UserLocation = UserLocation ,
2021-06-26 21:24:16 -05:00
UserLookAt = UserLookAt ,
SeeAVs = SeeAVs ,
AnyAVSounds = AnyAVSounds ,
GroupAVSounds = GroupAVSounds
2016-09-25 19:52:04 -05:00
} ;
2009-04-10 21:34:59 +00:00
2022-11-04 07:13:09 -05:00
Task req = client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload . Serialize ( ) ,
CancellationToken . None , null ) ;
2009-01-27 23:06:31 +00:00
}
2022-11-03 14:19:56 -05:00
else // lludp fallback
2009-01-27 23:06:31 +00:00
{
2019-08-11 10:08:35 -05:00
ParcelPropertiesUpdatePacket updatePacket = new ParcelPropertiesUpdatePacket
2016-09-25 19:52:04 -05:00
{
AgentData =
{
AgentID = simulator . Client . Self . AgentID ,
SessionID = simulator . Client . Self . SessionID
} ,
ParcelData =
{
LocalID = LocalID ,
AuthBuyerID = AuthBuyerID ,
Category = ( byte ) Category ,
Desc = Utils . StringToBytes ( Desc ) ,
GroupID = GroupID ,
LandingType = ( byte ) Landing ,
MediaAutoScale = ( Media . MediaAutoScale ) ? ( byte ) 0x1 : ( byte ) 0x0 ,
MediaID = Media . MediaID ,
MediaURL = Utils . StringToBytes ( Media . MediaURL ) ,
MusicURL = Utils . StringToBytes ( MusicURL ) ,
Name = Utils . StringToBytes ( Name )
}
} ;
2022-11-03 14:19:56 -05:00
if ( wantReply )
{
updatePacket . ParcelData . Flags = 1 ;
}
2019-08-11 10:08:35 -05:00
updatePacket . ParcelData . ParcelFlags = ( uint ) Flags ;
updatePacket . ParcelData . PassHours = PassHours ;
updatePacket . ParcelData . PassPrice = PassPrice ;
updatePacket . ParcelData . SalePrice = SalePrice ;
updatePacket . ParcelData . SnapshotID = SnapshotID ;
updatePacket . ParcelData . UserLocation = UserLocation ;
updatePacket . ParcelData . UserLookAt = UserLookAt ;
2009-01-27 23:06:31 +00:00
2019-08-11 10:08:35 -05:00
simulator . SendPacket ( updatePacket ) ;
2009-01-27 23:06:31 +00:00
}
2007-04-11 04:46:25 +00:00
2008-09-22 13:02:27 +00:00
UpdateOtherCleanTime ( simulator ) ;
2009-01-27 23:06:31 +00:00
2006-10-21 02:52:28 +00:00
}
2008-05-01 10:48:09 +00:00
/// <summary>
/// Set Autoreturn time
/// </summary>
2008-09-22 13:02:27 +00:00
/// <param name="simulator">Simulator to send the update to</param>
public void UpdateOtherCleanTime ( Simulator simulator )
2007-04-11 04:46:25 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelSetOtherCleanTimePacket request = new ParcelSetOtherCleanTimePacket
{
AgentData =
{
AgentID = simulator . Client . Self . AgentID ,
SessionID = simulator . Client . Self . SessionID
} ,
ParcelData =
{
LocalID = LocalID ,
OtherCleanTime = OtherCleanTime
}
} ;
2007-04-11 04:46:25 +00:00
2009-05-22 19:54:00 +00:00
simulator . SendPacket ( request ) ;
2007-04-11 04:46:25 +00:00
}
2007-01-19 13:15:12 +00:00
}
2007-04-11 04:46:25 +00:00
#endregion Parcel Class
2006-10-21 02:52:28 +00:00
/// <summary>
2007-01-19 13:15:12 +00:00
/// Parcel (subdivided simulator lots) subsystem
2006-10-21 02:52:28 +00:00
/// </summary>
public class ParcelManager
{
2007-04-11 04:46:25 +00:00
#region Structs
/// <summary>
2008-05-01 10:48:09 +00:00
/// Parcel Accesslist
2007-04-11 04:46:25 +00:00
/// </summary>
public struct ParcelAccessEntry
{
2008-07-28 22:23:48 +00:00
/// <summary>Agents <seealso cref="T:OpenMetaverse.UUID"/></summary>
2008-07-25 05:15:05 +00:00
public UUID AgentID ;
2007-04-11 04:46:25 +00:00
/// <summary></summary>
public DateTime Time ;
2008-10-18 23:53:30 +00:00
/// <summary>Flags for specific entry in white/black lists</summary>
2008-11-17 20:29:13 +00:00
public AccessList Flags ;
2007-04-11 04:46:25 +00:00
}
2008-05-01 10:48:09 +00:00
/// <summary>
/// Owners of primitives on parcel
/// </summary>
2007-08-26 16:52:08 +00:00
public struct ParcelPrimOwners
{
2008-07-28 22:23:48 +00:00
/// <summary>Prim Owners <seealso cref="T:OpenMetaverse.UUID"/></summary>
2008-07-25 05:15:05 +00:00
public UUID OwnerID ;
2008-05-01 10:48:09 +00:00
/// <summary>True of owner is group</summary>
2007-08-26 16:52:08 +00:00
public bool IsGroupOwned ;
2008-05-01 10:48:09 +00:00
/// <summary>Total count of prims owned by OwnerID</summary>
2007-08-26 16:52:08 +00:00
public int Count ;
2008-05-01 10:48:09 +00:00
/// <summary>true of OwnerID is currently online and is not a group</summary>
2007-08-26 16:52:08 +00:00
public bool OnlineStatus ;
2008-10-06 00:38:50 +00:00
/// <summary>The date of the most recent prim left by OwnerID</summary>
public DateTime NewestPrim ;
2007-08-26 16:52:08 +00:00
}
2008-07-26 08:50:37 +00:00
2007-04-11 04:46:25 +00:00
#endregion Structs
#region Delegates
2010-03-31 11:47:52 +00:00
/// <summary>
/// Called once parcel resource usage information has been collected
/// </summary>
/// <param name="success">Indicates if operation was successfull</param>
/// <param name="info">Parcel resource usage information</param>
public delegate void LandResourcesCallback ( bool success , LandResourcesInfo info ) ;
2007-03-19 13:38:10 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelDwellReplyEventArgs > m_DwellReply ;
2007-03-19 13:38:10 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>Raises the ParcelDwellReply event</summary>
/// <param name="e">A ParcelDwellReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelDwellReply ( ParcelDwellReplyEventArgs e )
{
EventHandler < ParcelDwellReplyEventArgs > handler = m_DwellReply ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
2007-08-26 16:52:08 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_DwellReplyLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestDwell"/> request</summary>
public event EventHandler < ParcelDwellReplyEventArgs > ParcelDwellReply
{
add { lock ( m_DwellReplyLock ) { m_DwellReply + = value ; } }
remove { lock ( m_DwellReplyLock ) { m_DwellReply - = value ; } }
}
2007-11-30 14:55:45 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelInfoReplyEventArgs > m_ParcelInfo ;
2008-01-12 07:19:30 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>Raises the ParcelInfoReply event</summary>
/// <param name="e">A ParcelInfoReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelInfoReply ( ParcelInfoReplyEventArgs e )
{
EventHandler < ParcelInfoReplyEventArgs > handler = m_ParcelInfo ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
2008-07-26 08:50:37 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelInfoLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestParcelInfo"/> request</summary>
public event EventHandler < ParcelInfoReplyEventArgs > ParcelInfoReply
{
add { lock ( m_ParcelInfoLock ) { m_ParcelInfo + = value ; } }
remove { lock ( m_ParcelInfoLock ) { m_ParcelInfo - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelPropertiesEventArgs > m_ParcelProperties ;
/// <summary>Raises the ParcelProperties event</summary>
/// <param name="e">A ParcelPropertiesEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelProperties ( ParcelPropertiesEventArgs e )
{
EventHandler < ParcelPropertiesEventArgs > handler = m_ParcelProperties ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelPropertiesLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestParcelProperties"/> request</summary>
public event EventHandler < ParcelPropertiesEventArgs > ParcelProperties
{
add { lock ( m_ParcelPropertiesLock ) { m_ParcelProperties + = value ; } }
remove { lock ( m_ParcelPropertiesLock ) { m_ParcelProperties - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelAccessListReplyEventArgs > m_ParcelACL ;
/// <summary>Raises the ParcelAccessListReply event</summary>
/// <param name="e">A ParcelAccessListReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelAccessListReply ( ParcelAccessListReplyEventArgs e )
{
EventHandler < ParcelAccessListReplyEventArgs > handler = m_ParcelACL ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
2009-07-10 01:48:42 +00:00
2009-10-17 05:50:51 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelACLLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestParcelAccessList"/> request</summary>
public event EventHandler < ParcelAccessListReplyEventArgs > ParcelAccessListReply
{
add { lock ( m_ParcelACLLock ) { m_ParcelACL + = value ; } }
remove { lock ( m_ParcelACLLock ) { m_ParcelACL - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelObjectOwnersReplyEventArgs > m_ParcelObjectOwnersReply ;
/// <summary>Raises the ParcelObjectOwnersReply event</summary>
/// <param name="e">A ParcelObjectOwnersReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelObjectOwnersReply ( ParcelObjectOwnersReplyEventArgs e )
{
EventHandler < ParcelObjectOwnersReplyEventArgs > handler = m_ParcelObjectOwnersReply ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelObjectOwnersLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestObjectOwners"/> request</summary>
public event EventHandler < ParcelObjectOwnersReplyEventArgs > ParcelObjectOwnersReply
{
add { lock ( m_ParcelObjectOwnersLock ) { m_ParcelObjectOwnersReply + = value ; } }
remove { lock ( m_ParcelObjectOwnersLock ) { m_ParcelObjectOwnersReply - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < SimParcelsDownloadedEventArgs > m_SimParcelsDownloaded ;
/// <summary>Raises the SimParcelsDownloaded event</summary>
/// <param name="e">A SimParcelsDownloadedEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnSimParcelsDownloaded ( SimParcelsDownloadedEventArgs e )
{
EventHandler < SimParcelsDownloadedEventArgs > handler = m_SimParcelsDownloaded ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_SimParcelsDownloadedLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestAllSimParcels"/> request</summary>
public event EventHandler < SimParcelsDownloadedEventArgs > SimParcelsDownloaded
{
add { lock ( m_SimParcelsDownloadedLock ) { m_SimParcelsDownloaded + = value ; } }
remove { lock ( m_SimParcelsDownloadedLock ) { m_SimParcelsDownloaded - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ForceSelectObjectsReplyEventArgs > m_ForceSelectObjects ;
/// <summary>Raises the ForceSelectObjectsReply event</summary>
/// <param name="e">A ForceSelectObjectsReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnForceSelectObjectsReply ( ForceSelectObjectsReplyEventArgs e )
{
EventHandler < ForceSelectObjectsReplyEventArgs > handler = m_ForceSelectObjects ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ForceSelectObjectsLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a <see cref="RequestForceSelectObjects"/> request</summary>
public event EventHandler < ForceSelectObjectsReplyEventArgs > ForceSelectObjectsReply
{
add { lock ( m_ForceSelectObjectsLock ) { m_ForceSelectObjects + = value ; } }
remove { lock ( m_ForceSelectObjectsLock ) { m_ForceSelectObjects - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelMediaUpdateReplyEventArgs > m_ParcelMediaUpdateReply ;
/// <summary>Raises the ParcelMediaUpdateReply event</summary>
/// <param name="e">A ParcelMediaUpdateReplyEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelMediaUpdateReply ( ParcelMediaUpdateReplyEventArgs e )
{
EventHandler < ParcelMediaUpdateReplyEventArgs > handler = m_ParcelMediaUpdateReply ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelMediaUpdateReplyLock = new object ( ) ;
/// <summary>Raised when the simulator responds to a Parcel Update request</summary>
public event EventHandler < ParcelMediaUpdateReplyEventArgs > ParcelMediaUpdateReply
{
add { lock ( m_ParcelMediaUpdateReplyLock ) { m_ParcelMediaUpdateReply + = value ; } }
remove { lock ( m_ParcelMediaUpdateReplyLock ) { m_ParcelMediaUpdateReply - = value ; } }
}
/// <summary>The event subscribers. null if no subcribers</summary>
private EventHandler < ParcelMediaCommandEventArgs > m_ParcelMediaCommand ;
/// <summary>Raises the ParcelMediaCommand event</summary>
/// <param name="e">A ParcelMediaCommandEventArgs object containing the
/// data returned from the simulator</param>
protected virtual void OnParcelMediaCommand ( ParcelMediaCommandEventArgs e )
{
EventHandler < ParcelMediaCommandEventArgs > handler = m_ParcelMediaCommand ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-17 05:50:51 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ParcelMediaCommandLock = new object ( ) ;
/// <summary>Raised when the parcel your agent is located sends a ParcelMediaCommand</summary>
public event EventHandler < ParcelMediaCommandEventArgs > ParcelMediaCommand
{
add { lock ( m_ParcelMediaCommandLock ) { m_ParcelMediaCommand + = value ; } }
remove { lock ( m_ParcelMediaCommandLock ) { m_ParcelMediaCommand - = value ; } }
}
2007-04-11 04:46:25 +00:00
#endregion Delegates
2008-07-21 21:12:59 +00:00
private GridClient Client ;
2008-09-06 10:19:46 +00:00
private AutoResetEvent WaitForSimParcel ;
2010-04-21 00:00:54 +00:00
2007-04-11 04:46:25 +00:00
#region Public Methods
2006-10-21 02:52:28 +00:00
/// <summary>
2007-01-19 13:15:12 +00:00
/// Default constructor
2006-10-21 02:52:28 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="client">A reference to the GridClient object</param>
public ParcelManager ( GridClient client )
2006-10-21 02:52:28 +00:00
{
Client = client ;
2009-10-17 05:50:51 +00:00
2006-10-21 02:52:28 +00:00
// Setup the callbacks
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ParcelInfoReply , ParcelInfoReplyHandler ) ;
2016-09-25 19:52:04 -05:00
Client . Network . RegisterEventCallback ( "ParcelObjectOwnersReply" , ParcelObjectOwnersReplyHandler ) ;
2008-03-10 09:19:51 +00:00
// CAPS packet handler, to allow for Media Data not contained in the message template
2016-09-25 19:52:04 -05:00
Client . Network . RegisterEventCallback ( "ParcelProperties" , ParcelPropertiesReplyHandler ) ;
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ParcelDwellReply , ParcelDwellReplyHandler ) ;
Client . Network . RegisterCallback ( PacketType . ParcelAccessListReply , ParcelAccessListReplyHandler ) ;
Client . Network . RegisterCallback ( PacketType . ForceObjectSelect , SelectParcelObjectsReplyHandler ) ;
Client . Network . RegisterCallback ( PacketType . ParcelMediaUpdate , ParcelMediaUpdateHandler ) ;
Client . Network . RegisterCallback ( PacketType . ParcelOverlay , ParcelOverlayHandler ) ;
Client . Network . RegisterCallback ( PacketType . ParcelMediaCommandMessage , ParcelMediaCommandMessagePacketHandler ) ;
2006-10-21 02:52:28 +00:00
}
/// <summary>
2007-03-19 13:38:10 +00:00
/// Request basic information for a single parcel
2006-10-21 02:52:28 +00:00
/// </summary>
2007-03-19 13:38:10 +00:00
/// <param name="parcelID">Simulator-local ID of the parcel</param>
2009-10-17 05:50:51 +00:00
public void RequestParcelInfo ( UUID parcelID )
2006-10-21 02:52:28 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelInfoRequestPacket request = new ParcelInfoRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { ParcelID = parcelID }
} ;
2006-10-21 02:52:28 +00:00
2007-03-19 13:38:10 +00:00
Client . Network . SendPacket ( request ) ;
2006-10-21 02:52:28 +00:00
}
/// <summary>
2007-03-19 13:38:10 +00:00
/// Request properties of a single parcel
2006-10-21 02:52:28 +00:00
/// </summary>
2007-03-19 13:38:10 +00:00
/// <param name="simulator">Simulator containing the parcel</param>
/// <param name="localID">Simulator-local ID of the parcel</param>
/// <param name="sequenceID">An arbitrary integer that will be returned
/// with the ParcelProperties reply, useful for distinguishing between
2007-04-11 04:46:25 +00:00
/// multiple simultaneous requests</param>
2009-10-17 05:50:51 +00:00
public void RequestParcelProperties ( Simulator simulator , int localID , int sequenceID )
2007-03-19 13:38:10 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelPropertiesRequestByIDPacket request = new ParcelPropertiesRequestByIDPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ParcelData =
{
LocalID = localID ,
SequenceID = sequenceID
}
} ;
2007-04-17 10:17:21 +00:00
Client . Network . SendPacket ( request , simulator ) ;
2007-03-19 13:38:10 +00:00
}
2007-04-10 10:05:25 +00:00
/// <summary>
/// Request the access list for a single parcel
/// </summary>
/// <param name="simulator">Simulator containing the parcel</param>
/// <param name="localID">Simulator-local ID of the parcel</param>
/// <param name="sequenceID">An arbitrary integer that will be returned
/// with the ParcelAccessList reply, useful for distinguishing between
/// multiple simultaneous requests</param>
2008-05-01 20:58:20 +00:00
/// <param name="flags"></param>
2009-10-17 05:50:51 +00:00
public void RequestParcelAccessList ( Simulator simulator , int localID , AccessList flags , int sequenceID )
2007-04-10 10:05:25 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelAccessListRequestPacket request = new ParcelAccessListRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
LocalID = localID ,
Flags = ( uint ) flags ,
SequenceID = sequenceID
}
} ;
2007-04-11 04:46:25 +00:00
Client . Network . SendPacket ( request , simulator ) ;
2007-04-10 10:05:25 +00:00
}
2007-03-19 13:38:10 +00:00
/// <summary>
/// Request properties of parcels using a bounding box selection
/// </summary>
/// <param name="simulator">Simulator containing the parcel</param>
/// <param name="north">Northern boundary of the parcel selection</param>
/// <param name="east">Eastern boundary of the parcel selection</param>
/// <param name="south">Southern boundary of the parcel selection</param>
/// <param name="west">Western boundary of the parcel selection</param>
/// <param name="sequenceID">An arbitrary integer that will be returned
/// with the ParcelProperties reply, useful for distinguishing between
/// different types of parcel property requests</param>
/// <param name="snapSelection">A boolean that is returned with the
/// ParcelProperties reply, useful for snapping focus to a single
/// parcel</param>
2009-10-17 05:50:51 +00:00
public void RequestParcelProperties ( Simulator simulator , float north , float east , float south , float west ,
2007-01-19 13:15:12 +00:00
int sequenceID , bool snapSelection )
2006-10-21 02:52:28 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelPropertiesRequestPacket request = new ParcelPropertiesRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ParcelData =
{
North = north ,
East = east ,
South = south ,
West = west ,
SequenceID = sequenceID ,
SnapSelection = snapSelection
}
} ;
2007-01-19 13:15:12 +00:00
Client . Network . SendPacket ( request , simulator ) ;
2006-10-21 02:52:28 +00:00
}
2007-11-29 19:38:32 +00:00
/// <summary>
/// Request all simulator parcel properties (used for populating the <code>Simulator.Parcels</code>
/// dictionary)
/// </summary>
/// <param name="simulator">Simulator to request parcels from (must be connected)</param>
public void RequestAllSimParcels ( Simulator simulator )
{
2008-09-06 10:19:46 +00:00
RequestAllSimParcels ( simulator , false , 750 ) ;
2008-03-07 17:43:51 +00:00
}
/// <summary>
/// Request all simulator parcel properties (used for populating the <code>Simulator.Parcels</code>
/// dictionary)
/// </summary>
/// <param name="simulator">Simulator to request parcels from (must be connected)</param>
2008-03-07 18:36:45 +00:00
/// <param name="refresh">If TRUE, will force a full refresh</param>
2008-07-28 22:23:48 +00:00
/// <param name="msDelay">Number of milliseconds to pause in between each request</param>
public void RequestAllSimParcels ( Simulator simulator , bool refresh , int msDelay )
2008-03-07 17:43:51 +00:00
{
2008-09-06 10:19:46 +00:00
if ( simulator . DownloadingParcelMap )
{
Logger . Log ( "Already downloading parcels in " + simulator . Name , Helpers . LogLevel . Info , Client ) ;
return ;
}
else
{
simulator . DownloadingParcelMap = true ;
WaitForSimParcel = new AutoResetEvent ( false ) ;
}
2008-03-07 17:43:51 +00:00
if ( refresh )
{
2022-11-03 14:19:56 -05:00
for ( int y = 0 ; y < 64 ; y + + )
2022-10-22 19:52:21 -05:00
{
for ( int x = 0 ; x < 64 ; x + + )
2008-05-22 05:35:10 +00:00
simulator . ParcelMap [ y , x ] = 0 ;
2022-10-22 19:52:21 -05:00
}
2008-03-07 17:43:51 +00:00
}
2019-10-20 23:56:44 -05:00
ThreadPool . QueueUserWorkItem ( ( _ ) = >
2007-11-29 19:38:32 +00:00
{
2008-09-06 10:19:46 +00:00
int count = 0 , timeouts = 0 , y , x ;
2008-08-02 01:49:20 +00:00
2007-12-04 03:59:21 +00:00
for ( y = 0 ; y < 64 ; y + + )
2007-11-29 19:38:32 +00:00
{
2007-12-04 03:59:21 +00:00
for ( x = 0 ; x < 64 ; x + + )
2007-11-30 14:55:45 +00:00
{
2008-07-29 16:52:44 +00:00
if ( ! Client . Network . Connected )
return ;
2007-12-04 03:59:21 +00:00
if ( simulator . ParcelMap [ y , x ] = = 0 )
{
2009-10-17 05:50:51 +00:00
Client . Parcels . RequestParcelProperties ( simulator ,
2007-12-04 03:59:21 +00:00
( y + 1 ) * 4.0f , ( x + 1 ) * 4.0f ,
2008-09-06 10:19:46 +00:00
y * 4.0f , x * 4.0f , int . MaxValue , false ) ;
2008-09-08 23:57:31 +00:00
// Wait the given amount of time for a reply before sending the next request
2008-09-06 10:19:46 +00:00
if ( ! WaitForSimParcel . WaitOne ( msDelay , false ) )
2008-09-08 23:57:31 +00:00
+ + timeouts ;
+ + count ;
2007-12-04 03:59:21 +00:00
}
2007-11-30 14:55:45 +00:00
}
}
2008-08-02 01:49:20 +00:00
Logger . Log ( String . Format (
2008-09-06 10:19:46 +00:00
"Full simulator parcel information retrieved. Sent {0} parcel requests. Current outgoing queue: {1}, Retry Count {2}" ,
count , Client . Network . OutboxCount , timeouts ) , Helpers . LogLevel . Info , Client ) ;
simulator . DownloadingParcelMap = false ;
2007-12-04 03:59:21 +00:00
} ) ;
2007-11-29 19:38:32 +00:00
}
2007-03-19 13:38:10 +00:00
/// <summary>
/// Request the dwell value for a parcel
/// </summary>
/// <param name="simulator">Simulator containing the parcel</param>
/// <param name="localID">Simulator-local ID of the parcel</param>
2009-10-17 05:50:51 +00:00
public void RequestDwell ( Simulator simulator , int localID )
2007-03-19 13:38:10 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelDwellRequestPacket request = new ParcelDwellRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
LocalID = localID ,
ParcelID = UUID . Zero
}
} ;
// Not used by clients
2007-03-19 13:38:10 +00:00
Client . Network . SendPacket ( request , simulator ) ;
}
/// <summary>
2008-05-01 20:58:20 +00:00
/// Send a request to Purchase a parcel of land
2007-03-19 13:38:10 +00:00
/// </summary>
2008-05-01 20:58:20 +00:00
/// <param name="simulator">The Simulator the parcel is located in</param>
/// <param name="localID">The parcels region specific local ID</param>
/// <param name="forGroup">true if this parcel is being purchased by a group</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupID">The groups <seealso cref="T:OpenMetaverse.UUID"/></param>
2008-05-01 20:58:20 +00:00
/// <param name="removeContribution">true to remove tier contribution if purchase is successful</param>
/// <param name="parcelArea">The parcels size</param>
/// <param name="parcelPrice">The purchase price of the parcel</param>
2007-03-19 13:38:10 +00:00
/// <returns></returns>
2008-07-25 05:15:05 +00:00
public void Buy ( Simulator simulator , int localID , bool forGroup , UUID groupID ,
2007-07-18 21:59:13 +00:00
bool removeContribution , int parcelArea , int parcelPrice )
2007-03-19 13:38:10 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelBuyPacket request = new ParcelBuyPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
Final = true ,
GroupID = groupID ,
LocalID = localID ,
IsGroupOwned = forGroup ,
RemoveContribution = removeContribution
} ,
ParcelData =
{
Area = parcelArea ,
Price = parcelPrice
}
} ;
2007-03-19 13:38:10 +00:00
2007-07-18 21:59:13 +00:00
2007-03-19 13:38:10 +00:00
Client . Network . SendPacket ( request , simulator ) ;
}
/// <summary>
2008-05-01 20:58:20 +00:00
/// Reclaim a parcel of land
2007-03-19 13:38:10 +00:00
/// </summary>
2008-05-01 20:58:20 +00:00
/// <param name="simulator">The simulator the parcel is in</param>
/// <param name="localID">The parcels region specific local ID</param>
2007-03-19 13:38:10 +00:00
public void Reclaim ( Simulator simulator , int localID )
{
2016-09-25 19:52:04 -05:00
ParcelReclaimPacket request = new ParcelReclaimPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { LocalID = localID }
} ;
2007-03-19 13:38:10 +00:00
Client . Network . SendPacket ( request , simulator ) ;
}
/// <summary>
2008-05-01 20:58:20 +00:00
/// Deed a parcel to a group
2007-03-19 13:38:10 +00:00
/// </summary>
2008-05-01 20:58:20 +00:00
/// <param name="simulator">The simulator the parcel is in</param>
/// <param name="localID">The parcels region specific local ID</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupID">The groups <seealso cref="T:OpenMetaverse.UUID"/></param>
2008-07-25 05:15:05 +00:00
public void DeedToGroup ( Simulator simulator , int localID , UUID groupID )
2007-03-19 13:38:10 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelDeedToGroupPacket request = new ParcelDeedToGroupPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
LocalID = localID ,
GroupID = groupID
}
} ;
2007-03-19 13:38:10 +00:00
Client . Network . SendPacket ( request , simulator ) ;
}
2007-08-26 16:52:08 +00:00
/// <summary>
/// Request prim owners of a parcel of land.
/// </summary>
/// <param name="simulator">Simulator parcel is in</param>
2008-05-01 20:58:20 +00:00
/// <param name="localID">The parcels region specific local ID</param>
2009-10-17 05:50:51 +00:00
public void RequestObjectOwners ( Simulator simulator , int localID )
2007-08-26 16:52:08 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelObjectOwnersRequestPacket request = new ParcelObjectOwnersRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ParcelData = { LocalID = localID }
} ;
2007-08-26 16:52:08 +00:00
Client . Network . SendPacket ( request , simulator ) ;
}
2007-03-19 13:38:10 +00:00
/// <summary>
2008-05-01 20:58:20 +00:00
/// Return objects from a parcel
2007-03-19 13:38:10 +00:00
/// </summary>
2008-05-01 20:58:20 +00:00
/// <param name="simulator">Simulator parcel is in</param>
/// <param name="localID">The parcels region specific local ID</param>
2008-07-21 21:12:59 +00:00
/// <param name="type">the type of objects to return, <seealso cref="T:OpenMetaverse.ObjectReturnType"/></param>
2008-07-28 22:23:48 +00:00
/// <param name="ownerIDs">A list containing object owners <seealso cref="OpenMetaverse.UUID"/>s to return</param>
2008-07-25 05:15:05 +00:00
public void ReturnObjects ( Simulator simulator , int localID , ObjectReturnType type , List < UUID > ownerIDs )
2007-03-19 13:38:10 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelReturnObjectsPacket request = new ParcelReturnObjectsPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ParcelData =
{
LocalID = localID ,
ReturnType = ( uint ) type
} ,
TaskIDs = new ParcelReturnObjectsPacket . TaskIDsBlock [ 1 ]
} ;
2007-03-19 13:38:10 +00:00
// A single null TaskID is (not) used for parcel object returns
2016-09-25 19:52:04 -05:00
request . TaskIDs [ 0 ] = new ParcelReturnObjectsPacket . TaskIDsBlock { TaskID = UUID . Zero } ;
2007-03-19 13:38:10 +00:00
// Convert the list of owner UUIDs to packet blocks if a list is given
if ( ownerIDs ! = null )
{
request . OwnerIDs = new ParcelReturnObjectsPacket . OwnerIDsBlock [ ownerIDs . Count ] ;
for ( int i = 0 ; i < ownerIDs . Count ; i + + )
{
2016-09-25 19:52:04 -05:00
request . OwnerIDs [ i ] = new ParcelReturnObjectsPacket . OwnerIDsBlock { OwnerID = ownerIDs [ i ] } ;
2007-03-19 13:38:10 +00:00
}
}
else
{
2022-04-19 18:22:05 -05:00
request . OwnerIDs = Array . Empty < ParcelReturnObjectsPacket . OwnerIDsBlock > ( ) ;
2007-03-19 13:38:10 +00:00
}
Client . Network . SendPacket ( request , simulator ) ;
2007-07-13 14:49:36 +00:00
}
/// <summary>
2008-05-01 20:58:20 +00:00
/// Subdivide (split) a parcel
2007-07-13 14:49:36 +00:00
/// </summary>
/// <param name="simulator"></param>
/// <param name="west"></param>
/// <param name="south"></param>
/// <param name="east"></param>
/// <param name="north"></param>
public void ParcelSubdivide ( Simulator simulator , float west , float south , float east , float north )
{
2016-09-25 19:52:04 -05:00
ParcelDividePacket divide = new ParcelDividePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ParcelData =
{
East = east ,
North = north ,
South = south ,
West = west
}
} ;
2007-07-13 14:49:36 +00:00
Client . Network . SendPacket ( divide , simulator ) ;
}
/// <summary>
2008-05-01 20:58:20 +00:00
/// Join two parcels of land creating a single parcel
2007-07-13 14:49:36 +00:00
/// </summary>
/// <param name="simulator"></param>
/// <param name="west"></param>
/// <param name="south"></param>
/// <param name="east"></param>
/// <param name="north"></param>
public void ParcelJoin ( Simulator simulator , float west , float south , float east , float north )
{
ParcelJoinPacket join = new ParcelJoinPacket ( ) ;
2007-11-06 09:26:10 +00:00
join . AgentData . AgentID = Client . Self . AgentID ;
join . AgentData . SessionID = Client . Self . SessionID ;
2007-07-13 14:49:36 +00:00
join . ParcelData . East = east ;
join . ParcelData . North = north ;
join . ParcelData . South = south ;
join . ParcelData . West = west ;
Client . Network . SendPacket ( join , simulator ) ;
2007-03-19 13:38:10 +00:00
}
2007-11-30 14:55:45 +00:00
/// <summary>
2008-05-01 20:58:20 +00:00
/// Get a parcels LocalID
2007-11-30 14:55:45 +00:00
/// </summary>
/// <param name="simulator">Simulator parcel is in</param>
2008-10-07 13:20:35 +00:00
/// <param name="position">Vector3 position in simulator (Z not used)</param>
2007-11-30 14:55:45 +00:00
/// <returns>0 on failure, or parcel LocalID on success.</returns>
2008-03-06 05:57:16 +00:00
/// <remarks>A call to <code>Parcels.RequestAllSimParcels</code> is required to populate map and
2007-11-30 14:55:45 +00:00
/// dictionary.</remarks>
2008-07-25 05:15:05 +00:00
public int GetParcelLocalID ( Simulator simulator , Vector3 position )
2007-11-30 14:55:45 +00:00
{
2008-12-01 21:13:24 +00:00
if ( simulator . ParcelMap [ ( byte ) position . Y / 4 , ( byte ) position . X / 4 ] > 0 )
{
return simulator . ParcelMap [ ( byte ) position . Y / 4 , ( byte ) position . X / 4 ] ;
}
else
{
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 ) ;
return 0 ;
}
2007-11-30 14:55:45 +00:00
}
2007-12-22 21:50:42 +00:00
/// <summary>
/// Terraform (raise, lower, etc) an area or whole parcel of land
/// </summary>
/// <param name="simulator">Simulator land area is in.</param>
/// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
/// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
/// <param name="brushSize">Size of area to modify</param>
/// <returns>true on successful request sent.</returns>
/// <remarks>Settings.STORE_LAND_PATCHES must be true,
/// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
public bool Terraform ( Simulator simulator , int localID , TerraformAction action , TerraformBrushSize brushSize )
{
return Terraform ( simulator , localID , 0f , 0f , 0f , 0f , action , brushSize , 1 ) ;
}
/// <summary>
/// Terraform (raise, lower, etc) an area or whole parcel of land
/// </summary>
/// <param name="simulator">Simulator land area is in.</param>
/// <param name="west">west border of area to modify</param>
/// <param name="south">south border of area to modify</param>
/// <param name="east">east border of area to modify</param>
/// <param name="north">north border of area to modify</param>
/// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
/// <param name="brushSize">Size of area to modify</param>
/// <returns>true on successful request sent.</returns>
/// <remarks>Settings.STORE_LAND_PATCHES must be true,
/// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
public bool Terraform ( Simulator simulator , float west , float south , float east , float north ,
TerraformAction action , TerraformBrushSize brushSize )
{
return Terraform ( simulator , - 1 , west , south , east , north , action , brushSize , 1 ) ;
}
/// <summary>
/// Terraform (raise, lower, etc) an area or whole parcel of land
/// </summary>
/// <param name="simulator">Simulator land area is in.</param>
/// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
/// <param name="west">west border of area to modify</param>
/// <param name="south">south border of area to modify</param>
/// <param name="east">east border of area to modify</param>
/// <param name="north">north border of area to modify</param>
/// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
/// <param name="brushSize">Size of area to modify</param>
/// <param name="seconds">How many meters + or - to lower, 1 = 1 meter</param>
/// <returns>true on successful request sent.</returns>
/// <remarks>Settings.STORE_LAND_PATCHES must be true,
/// Parcel information must be downloaded using <code>RequestAllSimParcels()</code></remarks>
public bool Terraform ( Simulator simulator , int localID , float west , float south , float east , float north ,
TerraformAction action , TerraformBrushSize brushSize , int seconds )
{
float height = 0f ;
int x , y ;
if ( localID = = - 1 )
{
x = ( int ) east - ( int ) west / 2 ;
y = ( int ) north - ( int ) south / 2 ;
}
else
{
Parcel p ;
2008-06-25 17:57:59 +00:00
if ( ! simulator . Parcels . TryGetValue ( localID , out p ) )
2007-12-22 21:50:42 +00:00
{
2008-05-06 23:57:26 +00:00
Logger . Log ( String . Format ( "Can't find parcel {0} in simulator {1}" , localID , simulator ) ,
Helpers . LogLevel . Warning , Client ) ;
2007-12-22 21:50:42 +00:00
return false ;
}
x = ( int ) p . AABBMax . X - ( int ) p . AABBMin . X / 2 ;
y = ( int ) p . AABBMax . Y - ( int ) p . AABBMin . Y / 2 ;
}
2010-04-21 00:00:54 +00:00
if ( ! simulator . TerrainHeightAtPoint ( x , y , out height ) )
2007-12-22 21:50:42 +00:00
{
2008-05-06 23:57:26 +00:00
Logger . Log ( "Land Patch not stored for location" , Helpers . LogLevel . Warning , Client ) ;
2007-12-22 21:50:42 +00:00
return false ;
}
Terraform ( simulator , localID , west , south , east , north , action , brushSize , seconds , height ) ;
return true ;
}
/// <summary>
/// Terraform (raise, lower, etc) an area or whole parcel of land
/// </summary>
/// <param name="simulator">Simulator land area is in.</param>
/// <param name="localID">LocalID of parcel, or -1 if using bounding box</param>
/// <param name="west">west border of area to modify</param>
/// <param name="south">south border of area to modify</param>
/// <param name="east">east border of area to modify</param>
/// <param name="north">north border of area to modify</param>
/// <param name="action">From Enum, Raise, Lower, Level, Smooth, Etc.</param>
/// <param name="brushSize">Size of area to modify</param>
/// <param name="seconds">How many meters + or - to lower, 1 = 1 meter</param>
/// <param name="height">Height at which the terraform operation is acting at</param>
public void Terraform ( Simulator simulator , int localID , float west , float south , float east , float north ,
TerraformAction action , TerraformBrushSize brushSize , int seconds , float height )
{
2016-09-25 19:52:04 -05:00
ModifyLandPacket land = new ModifyLandPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ModifyBlock =
{
Action = ( byte ) action ,
BrushSize = ( byte ) brushSize ,
Seconds = seconds ,
Height = height
} ,
ParcelData = new ModifyLandPacket . ParcelDataBlock [ 1 ]
} ;
2007-12-22 21:50:42 +00:00
2016-09-25 19:52:04 -05:00
land . ParcelData [ 0 ] = new ModifyLandPacket . ParcelDataBlock
{
LocalID = localID ,
West = west ,
South = south ,
East = east ,
North = north
} ;
2007-12-22 21:50:42 +00:00
2010-06-29 12:41:12 +00:00
land . ModifyBlockExtended = new ModifyLandPacket . ModifyBlockExtendedBlock [ 1 ] ;
2016-09-25 19:52:04 -05:00
land . ModifyBlockExtended [ 0 ] = new ModifyLandPacket . ModifyBlockExtendedBlock { BrushSize = ( float ) brushSize } ;
2010-06-29 12:41:12 +00:00
2007-12-22 21:50:42 +00:00
Client . Network . SendPacket ( land , simulator ) ;
}
2008-01-12 07:19:30 +00:00
/// <summary>
/// Sends a request to the simulator to return a list of objects owned by specific owners
/// </summary>
/// <param name="localID">Simulator local ID of parcel</param>
/// <param name="selectType">Owners, Others, Etc</param>
2008-07-30 06:51:51 +00:00
/// <param name="ownerID">List containing keys of avatars objects to select;
2008-03-18 18:07:23 +00:00
/// if List is null will return Objects of type <c>selectType</c></param>
2011-08-14 11:54:08 +00:00
/// <remarks>Response data is returned in the event <seealso cref="E:ForceSelectObjectsReply"/></remarks>
2009-10-17 05:50:51 +00:00
public void RequestSelectObjects ( int localID , ObjectReturnType selectType , UUID ownerID )
2008-01-12 07:19:30 +00:00
{
2009-10-17 05:50:51 +00:00
ParcelSelectObjectsPacket select = new ParcelSelectObjectsPacket ( ) ;
select . AgentData . AgentID = Client . Self . AgentID ;
select . AgentData . SessionID = Client . Self . SessionID ;
2008-01-12 07:19:30 +00:00
2009-10-17 05:50:51 +00:00
select . ParcelData . LocalID = localID ;
select . ParcelData . ReturnType = ( uint ) selectType ;
2008-03-11 08:15:15 +00:00
2009-10-17 05:50:51 +00:00
select . ReturnIDs = new ParcelSelectObjectsPacket . ReturnIDsBlock [ 1 ] ;
2016-09-25 19:52:04 -05:00
select . ReturnIDs [ 0 ] = new ParcelSelectObjectsPacket . ReturnIDsBlock { ReturnID = ownerID } ;
2009-10-17 05:50:51 +00:00
Client . Network . SendPacket ( select ) ;
2008-01-12 07:19:30 +00:00
}
2008-02-13 19:34:10 +00:00
/// <summary>
/// Eject and optionally ban a user from a parcel
/// </summary>
/// <param name="targetID">target key of avatar to eject</param>
/// <param name="ban">true to also ban target</param>
2008-07-25 05:15:05 +00:00
public void EjectUser ( UUID targetID , bool ban )
2008-02-13 19:34:10 +00:00
{
2016-09-25 19:52:04 -05:00
EjectUserPacket eject = new EjectUserPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { TargetID = targetID }
} ;
eject . Data . Flags = ban ? ( uint ) 1 : 0 ;
2008-02-13 19:34:10 +00:00
Client . Network . SendPacket ( eject ) ;
}
/// <summary>
/// Freeze or unfreeze an avatar over your land
/// </summary>
/// <param name="targetID">target key to freeze</param>
/// <param name="freeze">true to freeze, false to unfreeze</param>
2008-07-25 05:15:05 +00:00
public void FreezeUser ( UUID targetID , bool freeze )
2008-02-13 19:34:10 +00:00
{
2016-09-25 19:52:04 -05:00
FreezeUserPacket frz = new FreezeUserPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { TargetID = targetID }
} ;
frz . Data . Flags = freeze ? ( uint ) 0 : 1 ;
2008-02-13 19:34:10 +00:00
Client . Network . SendPacket ( frz ) ;
}
2008-06-08 19:28:24 +00:00
/// <summary>
/// Abandon a parcel of land
/// </summary>
/// <param name="simulator">Simulator parcel is in</param>
/// <param name="localID">Simulator local ID of parcel</param>
public void ReleaseParcel ( Simulator simulator , int localID )
{
2016-09-25 19:52:04 -05:00
ParcelReleasePacket abandon = new ParcelReleasePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { LocalID = localID }
} ;
2008-06-08 19:28:24 +00:00
Client . Network . SendPacket ( abandon , simulator ) ;
}
2009-06-26 06:51:41 +00:00
/// <summary>
/// Requests the UUID of the parcel in a remote region at a specified location
/// </summary>
/// <param name="location">Location of the parcel in the remote region</param>
/// <param name="regionHandle">Remote region handle</param>
/// <param name="regionID">Remote region UUID</param>
/// <returns>If successful UUID of the remote parcel, UUID.Zero otherwise</returns>
2022-11-03 14:19:56 -05:00
public async Task < UUID > RequestRemoteParcelIDAsync ( Vector3 location , ulong regionHandle , UUID regionID )
2009-06-26 06:51:41 +00:00
{
2011-12-03 17:14:53 +00:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
return UUID . Zero ;
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "RemoteParcelRequest" ) ;
2009-06-26 06:51:41 +00:00
2022-11-03 14:19:56 -05:00
if ( cap ! = null )
2009-06-26 06:51:41 +00:00
{
2016-09-25 19:52:04 -05:00
RemoteParcelRequestRequest msg = new RemoteParcelRequestRequest
{
Location = location ,
RegionHandle = regionHandle ,
RegionID = regionID
} ;
2009-06-26 06:51:41 +00:00
try
{
2022-11-03 14:19:56 -05:00
OSD res = null ;
2022-11-04 07:13:09 -05:00
await Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , msg . Serialize ( ) , CancellationToken . None ,
( response , data , error ) = > res = OSDParser . Deserialize ( data ) ) ;
2022-11-03 14:19:56 -05:00
if ( res is OSDMap result )
{
RemoteParcelRequestReply response = new RemoteParcelRequestReply ( ) ;
response . Deserialize ( result ) ;
return response . ParcelID ;
}
2009-06-26 06:51:41 +00:00
}
2022-11-03 14:19:56 -05:00
catch ( Exception ex )
2009-06-26 06:51:41 +00:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Failed to fetch remote parcel ID" , Helpers . LogLevel . Debug , Client , ex ) ;
2009-06-26 06:51:41 +00:00
}
}
return UUID . Zero ;
}
2010-03-31 11:47:52 +00:00
2022-11-11 12:54:23 -06:00
/// <summary>
/// Requests the UUID of the parcel in a remote region at a specified location
/// </summary>
/// <param name="location">Location of the parcel in the remote region</param>
/// <param name="regionHandle">Remote region handle</param>
/// <param name="regionID">Remote region UUID</param>
/// <returns>If successful UUID of the remote parcel, UUID.Zero otherwise</returns>
public UUID RequestRemoteParcelID ( Vector3 location , ulong regionHandle , UUID regionID )
{
return RequestRemoteParcelIDAsync ( location , regionHandle , regionID ) . Result ;
}
2010-03-31 11:47:52 +00:00
/// <summary>
/// Retrieves information on resources used by the parcel
/// </summary>
/// <param name="parcelID">UUID of the parcel</param>
/// <param name="getDetails">Should per object resource usage be requested</param>
/// <param name="callback">Callback invoked when the request is complete</param>
2022-11-03 14:19:56 -05:00
public void GetParcelResources ( UUID parcelID , bool getDetails , LandResourcesCallback callback )
2010-03-31 11:47:52 +00:00
{
try
{
2022-11-03 14:19:56 -05:00
LandResourcesRequest req = new LandResourcesRequest { ParcelID = parcelID } ;
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "LandResources" ) ;
Task httpReq = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , req . Serialize ( ) ,
2022-11-04 07:13:09 -05:00
CancellationToken . None , ( httpResponse , data , error ) = >
2010-03-31 11:47:52 +00:00
{
2022-11-03 14:19:56 -05:00
try
2010-03-31 11:47:52 +00:00
{
2022-11-03 14:19:56 -05:00
if ( error ! = null )
{
callback ( false , null ) ;
}
OSD result = OSDParser . Deserialize ( data ) ;
LandResourcesMessage landResourcesMessage = new LandResourcesMessage ( ) ;
landResourcesMessage . Deserialize ( ( OSDMap ) result ) ;
OSD summaryResponse = null ;
AsyncHelper . Sync ( ( ) = > Client . HttpCapsClient . GetRequestAsync (
Client . Network . CurrentSim . Caps . CapabilityURI ( "ScriptResourceSummary" ) ,
2022-11-04 07:13:09 -05:00
CancellationToken . None ,
2022-11-20 00:46:46 -06:00
( response , respData , err ) = > summaryResponse = OSDParser . Deserialize ( respData ) ) ) ;
2022-11-03 14:19:56 -05:00
LandResourcesInfo resInfo = new LandResourcesInfo ( ) ;
resInfo . Deserialize ( ( OSDMap ) summaryResponse ) ;
if ( landResourcesMessage . ScriptResourceDetails ! = null & & getDetails )
{
OSD detailResponse = null ;
AsyncHelper . Sync ( ( ) = > Client . HttpCapsClient . GetRequestAsync (
Client . Network . CurrentSim . Caps . CapabilityURI ( "ScriptResourceDetails" ) ,
2022-11-04 07:13:09 -05:00
CancellationToken . None ,
2022-11-20 00:46:46 -06:00
( response , respData , err ) = > detailResponse = OSDParser . Deserialize ( respData ) ) ) ;
2022-11-03 14:19:56 -05:00
resInfo . Deserialize ( ( OSDMap ) detailResponse ) ;
}
callback ( true , resInfo ) ;
2010-03-31 11:47:52 +00:00
}
2022-11-03 14:19:56 -05:00
catch ( Exception ex )
2010-03-31 11:47:52 +00:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Failed fetching land resources" , Helpers . LogLevel . Error , Client , ex ) ;
callback ( false , null ) ;
2010-03-31 11:47:52 +00:00
}
2022-11-04 07:13:09 -05:00
} ) ;
2010-03-31 11:47:52 +00:00
}
catch ( Exception ex )
{
Logger . Log ( "Failed fetching land resources:" , Helpers . LogLevel . Error , Client , ex ) ;
callback ( false , null ) ;
}
}
2007-04-11 04:46:25 +00:00
#endregion Public Methods
#region Packet Handlers
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ParcelDwellReply"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void ParcelDwellReplyHandler ( object sender , PacketReceivedEventArgs e )
2009-10-17 05:50:51 +00:00
{
2019-10-08 20:20:32 -05:00
if ( m_DwellReply ! = null | | Client . Settings . ALWAYS_REQUEST_PARCEL_DWELL )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-01-19 13:15:12 +00:00
ParcelDwellReplyPacket dwell = ( ParcelDwellReplyPacket ) packet ;
2006-10-21 02:52:28 +00:00
2007-11-29 19:38:32 +00:00
lock ( simulator . Parcels . Dictionary )
{
if ( simulator . Parcels . Dictionary . ContainsKey ( dwell . Data . LocalID ) )
{
Parcel parcel = simulator . Parcels . Dictionary [ dwell . Data . LocalID ] ;
parcel . Dwell = dwell . Data . Dwell ;
simulator . Parcels . Dictionary [ dwell . Data . LocalID ] = parcel ;
}
}
2009-10-17 05:50:51 +00:00
if ( m_DwellReply ! = null )
2008-03-07 18:36:45 +00:00
{
2009-10-17 05:50:51 +00:00
OnParcelDwellReply ( new ParcelDwellReplyEventArgs ( dwell . Data . ParcelID , dwell . Data . LocalID , dwell . Data . Dwell ) ) ;
2008-03-07 18:36:45 +00:00
}
2006-10-21 02:52:28 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ParcelInfoReply"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void ParcelInfoReplyHandler ( object sender , PacketReceivedEventArgs e )
2016-09-25 19:52:04 -05:00
{
if ( m_ParcelInfo = = null ) return ;
Packet packet = e . Packet ;
ParcelInfoReplyPacket info = ( ParcelInfoReplyPacket ) packet ;
ParcelInfo parcelInfo = new ParcelInfo
2006-10-21 02:52:28 +00:00
{
2016-09-25 19:52:04 -05:00
ActualArea = info . Data . ActualArea ,
AuctionID = info . Data . AuctionID ,
BillableArea = info . Data . BillableArea ,
Description = Utils . BytesToString ( info . Data . Desc ) ,
Dwell = info . Data . Dwell ,
GlobalX = info . Data . GlobalX ,
GlobalY = info . Data . GlobalY ,
GlobalZ = info . Data . GlobalZ ,
ID = info . Data . ParcelID ,
2019-10-08 20:20:32 -05:00
Mature = ( ( info . Data . Flags & 1 ) ! = 0 ) ,
2016-09-25 19:52:04 -05:00
Name = Utils . BytesToString ( info . Data . Name ) ,
OwnerID = info . Data . OwnerID ,
SalePrice = info . Data . SalePrice ,
SimName = Utils . BytesToString ( info . Data . SimName ) ,
SnapshotID = info . Data . SnapshotID
} ;
OnParcelInfoReply ( new ParcelInfoReplyEventArgs ( parcelInfo ) ) ;
2006-10-21 02:52:28 +00:00
}
2009-10-17 05:50:51 +00:00
protected void ParcelPropertiesReplyHandler ( string capsKey , IMessage message , Simulator simulator )
2016-09-25 19:52:04 -05:00
{
if ( m_ParcelProperties = = null & & Client . Settings . PARCEL_TRACKING ! = true ) return ;
ParcelPropertiesMessage msg = ( ParcelPropertiesMessage ) message ;
Parcel parcel = new Parcel ( msg . LocalID )
2009-04-10 21:34:59 +00:00
{
2016-09-25 19:52:04 -05:00
AABBMax = msg . AABBMax ,
AABBMin = msg . AABBMin ,
Area = msg . Area ,
AuctionID = msg . AuctionID ,
AuthBuyerID = msg . AuthBuyerID ,
Bitmap = msg . Bitmap ,
Category = msg . Category ,
ClaimDate = msg . ClaimDate ,
ClaimPrice = msg . ClaimPrice ,
Desc = msg . Desc ,
Flags = msg . ParcelFlags ,
GroupID = msg . GroupID ,
GroupPrims = msg . GroupPrims ,
IsGroupOwned = msg . IsGroupOwned ,
Landing = msg . LandingType ,
MaxPrims = msg . MaxPrims ,
Media =
2008-03-10 09:19:51 +00:00
{
2016-09-25 19:52:04 -05:00
MediaAutoScale = msg . MediaAutoScale ,
MediaID = msg . MediaID ,
MediaURL = msg . MediaURL
} ,
MusicURL = msg . MusicURL ,
Name = msg . Name ,
OtherCleanTime = msg . OtherCleanTime ,
OtherCount = msg . OtherCount ,
OtherPrims = msg . OtherPrims ,
OwnerID = msg . OwnerID ,
OwnerPrims = msg . OwnerPrims ,
ParcelPrimBonus = msg . ParcelPrimBonus ,
PassHours = msg . PassHours ,
PassPrice = msg . PassPrice ,
PublicCount = msg . PublicCount ,
RegionDenyAgeUnverified = msg . RegionDenyAgeUnverified ,
RegionDenyAnonymous = msg . RegionDenyAnonymous ,
RegionPushOverride = msg . RegionPushOverride ,
2021-06-26 21:24:16 -05:00
RentPrice = msg . RentPrice ,
SeeAVs = msg . SeeAVs ,
AnyAVSounds = msg . AnyAVSounds ,
GroupAVSounds = msg . GroupAVSounds
2016-09-25 19:52:04 -05:00
} ;
ParcelResult result = msg . RequestResult ;
parcel . SalePrice = msg . SalePrice ;
int selectedPrims = msg . SelectedPrims ;
parcel . SelfCount = msg . SelfCount ;
int sequenceID = msg . SequenceID ;
parcel . SimWideMaxPrims = msg . SimWideMaxPrims ;
parcel . SimWideTotalPrims = msg . SimWideTotalPrims ;
bool snapSelection = msg . SnapSelection ;
parcel . SnapshotID = msg . SnapshotID ;
parcel . Status = msg . Status ;
parcel . TotalPrims = msg . TotalPrims ;
parcel . UserLocation = msg . UserLocation ;
parcel . UserLookAt = msg . UserLookAt ;
parcel . Media . MediaDesc = msg . MediaDesc ;
parcel . Media . MediaHeight = msg . MediaHeight ;
parcel . Media . MediaWidth = msg . MediaWidth ;
parcel . Media . MediaLoop = msg . MediaLoop ;
parcel . Media . MediaType = msg . MediaType ;
parcel . ObscureMedia = msg . ObscureMedia ;
parcel . ObscureMusic = msg . ObscureMusic ;
if ( Client . Settings . PARCEL_TRACKING )
{
lock ( simulator . Parcels . Dictionary )
simulator . Parcels . Dictionary [ parcel . LocalID ] = parcel ;
2008-03-10 09:19:51 +00:00
2016-09-25 19:52:04 -05:00
bool set = false ;
int y , x , index , bit ;
for ( y = 0 ; y < 64 ; y + + )
{
for ( x = 0 ; x < 64 ; x + + )
2008-03-10 09:19:51 +00:00
{
2016-09-25 19:52:04 -05:00
index = ( y * 64 ) + x ;
bit = index % 8 ;
index > > = 3 ;
if ( ( parcel . Bitmap [ index ] & ( 1 < < bit ) ) ! = 0 )
2008-03-10 09:19:51 +00:00
{
2016-09-25 19:52:04 -05:00
simulator . ParcelMap [ y , x ] = parcel . LocalID ;
set = true ;
2008-03-10 09:19:51 +00:00
}
}
2016-09-25 19:52:04 -05:00
}
2008-12-05 01:34:24 +00:00
2016-09-25 19:52:04 -05:00
if ( ! set )
{
Logger . Log ( "Received a parcel with a bitmap that did not map to any locations" ,
Helpers . LogLevel . Warning ) ;
2008-03-10 09:19:51 +00:00
}
2016-09-25 19:52:04 -05:00
}
2008-03-10 09:19:51 +00:00
2016-09-25 19:52:04 -05:00
if ( sequenceID . Equals ( int . MaxValue ) )
WaitForSimParcel ? . Set ( ) ;
2008-12-05 01:34:24 +00:00
2016-09-25 19:52:04 -05:00
// auto request acl, will be stored in parcel tracking dictionary if enabled
if ( Client . Settings . ALWAYS_REQUEST_PARCEL_ACL )
2022-10-22 19:52:21 -05:00
{
2016-09-25 19:52:04 -05:00
Client . Parcels . RequestParcelAccessList ( simulator , parcel . LocalID ,
AccessList . Both , sequenceID ) ;
2022-10-22 19:52:21 -05:00
}
2008-03-10 09:19:51 +00:00
2016-09-25 19:52:04 -05:00
// auto request dwell, will be stored in parcel tracking dictionary if enables
if ( Client . Settings . ALWAYS_REQUEST_PARCEL_DWELL )
Client . Parcels . RequestDwell ( simulator , parcel . LocalID ) ;
2008-03-10 09:19:51 +00:00
2016-09-25 19:52:04 -05:00
// Fire the callback for parcel properties being received
if ( m_ParcelProperties ! = null )
{
OnParcelProperties ( new ParcelPropertiesEventArgs ( simulator , parcel , result , selectedPrims , sequenceID , snapSelection ) ) ;
}
2008-03-10 09:19:51 +00:00
2016-09-25 19:52:04 -05:00
// Check if all of the simulator parcels have been retrieved, if so fire another callback
if ( simulator . IsParcelMapFull ( ) & & m_SimParcelsDownloaded ! = null )
{
OnSimParcelsDownloaded ( new SimParcelsDownloadedEventArgs ( simulator , simulator . Parcels , simulator . ParcelMap ) ) ;
2008-03-10 09:19:51 +00:00
}
}
2006-10-21 02:52:28 +00:00
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ParcelAccessListReply"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void ParcelAccessListReplyHandler ( object sender , PacketReceivedEventArgs e )
2007-03-16 20:02:41 +00:00
{
2019-10-08 20:20:32 -05:00
if ( m_ParcelACL ! = null | | Client . Settings . ALWAYS_REQUEST_PARCEL_ACL )
2007-03-16 20:02:41 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-03-16 20:02:41 +00:00
ParcelAccessListReplyPacket reply = ( ParcelAccessListReplyPacket ) packet ;
2008-10-18 23:53:30 +00:00
List < ParcelAccessEntry > accessList = new List < ParcelAccessEntry > ( reply . List . Length ) ;
2016-09-25 19:52:04 -05:00
foreach ( ParcelAccessListReplyPacket . ListBlock t in reply . List )
2008-10-18 23:53:30 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelAccessEntry pae = new ParcelAccessEntry
{
AgentID = t . ID ,
Time = Utils . UnixTimeToDateTime ( ( uint ) t . Time ) ,
Flags = ( AccessList ) t . Flags
} ;
2007-03-16 20:02:41 +00:00
2008-10-18 23:53:30 +00:00
accessList . Add ( pae ) ;
}
2007-03-16 20:02:41 +00:00
2008-10-18 23:53:30 +00:00
lock ( simulator . Parcels . Dictionary )
2007-11-29 19:38:32 +00:00
{
2008-10-18 23:53:30 +00:00
if ( simulator . Parcels . Dictionary . ContainsKey ( reply . Data . LocalID ) )
{
Parcel parcel = simulator . Parcels . Dictionary [ reply . Data . LocalID ] ;
if ( ( AccessList ) reply . Data . Flags = = AccessList . Ban )
parcel . AccessBlackList = accessList ;
else
parcel . AccessWhiteList = accessList ;
simulator . Parcels . Dictionary [ reply . Data . LocalID ] = parcel ;
}
2007-11-29 19:38:32 +00:00
}
2008-10-18 23:53:30 +00:00
2007-11-29 19:38:32 +00:00
2009-10-17 05:50:51 +00:00
if ( m_ParcelACL ! = null )
2008-03-07 18:36:45 +00:00
{
2009-10-17 05:50:51 +00:00
OnParcelAccessListReply ( new ParcelAccessListReplyEventArgs ( simulator , reply . Data . SequenceID , reply . Data . LocalID ,
reply . Data . Flags , accessList ) ) ;
2008-03-07 18:36:45 +00:00
}
2007-03-16 20:02:41 +00:00
}
}
2009-10-28 08:01:52 +00:00
2009-10-17 05:50:51 +00:00
protected void ParcelObjectOwnersReplyHandler ( string capsKey , IMessage message , Simulator simulator )
2007-08-26 16:52:08 +00:00
{
2009-10-17 05:50:51 +00:00
if ( m_ParcelObjectOwnersReply ! = null )
2007-08-26 16:52:08 +00:00
{
List < ParcelPrimOwners > primOwners = new List < ParcelPrimOwners > ( ) ;
2008-03-11 08:15:15 +00:00
2009-04-24 04:39:44 +00:00
ParcelObjectOwnersReplyMessage msg = ( ParcelObjectOwnersReplyMessage ) message ;
2009-04-13 09:32:25 +00:00
2016-09-25 19:52:04 -05:00
foreach ( ParcelObjectOwnersReplyMessage . PrimOwner t in msg . PrimOwnersBlock )
2008-10-06 01:12:05 +00:00
{
2016-09-25 19:52:04 -05:00
ParcelPrimOwners primOwner = new ParcelPrimOwners
{
OwnerID = t . OwnerID ,
Count = t . Count ,
IsGroupOwned = t . IsGroupOwned ,
OnlineStatus = t . OnlineStatus ,
NewestPrim = t . TimeStamp
} ;
2009-04-10 21:34:59 +00:00
primOwners . Add ( primOwner ) ;
2008-10-06 01:12:05 +00:00
}
2009-10-17 05:50:51 +00:00
OnParcelObjectOwnersReply ( new ParcelObjectOwnersReplyEventArgs ( simulator , primOwners ) ) ;
2009-04-10 21:34:59 +00:00
}
2007-08-26 16:52:08 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ForceSelectObjectsReply"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void SelectParcelObjectsReplyHandler ( object sender , PacketReceivedEventArgs e )
2008-01-12 07:19:30 +00:00
{
2016-09-25 19:52:04 -05:00
if ( m_ForceSelectObjects = = null ) return ;
2009-10-28 08:01:52 +00:00
2016-09-25 19:52:04 -05:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2008-01-12 07:19:30 +00:00
2016-09-25 19:52:04 -05:00
ForceObjectSelectPacket reply = ( ForceObjectSelectPacket ) packet ;
List < uint > objectIDs = new List < uint > ( reply . Data . Length ) ;
objectIDs . AddRange ( reply . Data . Select ( t = > t . LocalID ) ) ;
2009-10-17 05:50:51 +00:00
2016-09-25 19:52:04 -05:00
OnForceSelectObjectsReply ( new ForceSelectObjectsReplyEventArgs ( simulator , objectIDs , reply . _Header . ResetList ) ) ;
2008-01-12 07:19:30 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ParcelMediaUpdateReply"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void ParcelMediaUpdateHandler ( object sender , PacketReceivedEventArgs e )
2008-07-26 08:50:37 +00:00
{
2016-09-25 19:52:04 -05:00
if ( m_ParcelMediaUpdateReply = = null ) return ;
2009-10-28 08:01:52 +00:00
2016-09-25 19:52:04 -05:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-17 05:50:51 +00:00
2016-09-25 19:52:04 -05:00
ParcelMediaUpdatePacket reply = ( ParcelMediaUpdatePacket ) packet ;
ParcelMedia media = new ParcelMedia
{
2019-10-08 20:20:32 -05:00
MediaAutoScale = ( reply . DataBlock . MediaAutoScale = = ( byte ) 0x1 ) ,
2016-09-25 19:52:04 -05:00
MediaID = reply . DataBlock . MediaID ,
MediaDesc = Utils . BytesToString ( reply . DataBlockExtended . MediaDesc ) ,
MediaHeight = reply . DataBlockExtended . MediaHeight ,
2019-10-08 20:20:32 -05:00
MediaLoop = ( ( reply . DataBlockExtended . MediaLoop & 1 ) ! = 0 ) ,
2016-09-25 19:52:04 -05:00
MediaType = Utils . BytesToString ( reply . DataBlockExtended . MediaType ) ,
MediaWidth = reply . DataBlockExtended . MediaWidth ,
MediaURL = Utils . BytesToString ( reply . DataBlock . MediaURL )
} ;
2009-10-17 05:50:51 +00:00
2016-09-25 19:52:04 -05:00
OnParcelMediaUpdateReply ( new ParcelMediaUpdateReplyEventArgs ( simulator , media ) ) ;
2008-07-26 08:50:37 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ParcelOverlayHandler ( object sender , PacketReceivedEventArgs e )
2008-09-22 13:02:27 +00:00
{
const int OVERLAY_COUNT = 4 ;
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2008-09-22 13:02:27 +00:00
ParcelOverlayPacket overlay = ( ParcelOverlayPacket ) packet ;
if ( overlay . ParcelData . SequenceID > = 0 & & overlay . ParcelData . SequenceID < OVERLAY_COUNT )
{
int length = overlay . ParcelData . Data . Length ;
Buffer . BlockCopy ( overlay . ParcelData . Data , 0 , simulator . ParcelOverlay ,
overlay . ParcelData . SequenceID * length , length ) ;
simulator . ParcelOverlaysReceived + + ;
if ( simulator . ParcelOverlaysReceived > = OVERLAY_COUNT )
{
// TODO: ParcelOverlaysReceived should become internal, and reset to zero every
// time it hits four. Also need a callback here
}
}
else
{
Logger . Log ( "Parcel overlay with sequence ID of " + overlay . ParcelData . SequenceID +
2019-10-08 20:20:32 -05:00
" received from " + simulator , Helpers . LogLevel . Warning , Client ) ;
2008-09-22 13:02:27 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-17 05:50:51 +00:00
/// <remarks>Raises the <see cref="ParcelMediaCommand"/> event</remarks>
2009-10-28 08:01:52 +00:00
protected void ParcelMediaCommandMessagePacketHandler ( object sender , PacketReceivedEventArgs e )
2009-07-10 01:48:42 +00:00
{
2016-09-25 19:52:04 -05:00
if ( m_ParcelMediaCommand = = null ) return ;
2009-10-28 08:01:52 +00:00
2016-09-25 19:52:04 -05:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-17 05:50:51 +00:00
2016-09-25 19:52:04 -05:00
ParcelMediaCommandMessagePacket pmc = ( ParcelMediaCommandMessagePacket ) packet ;
ParcelMediaCommandMessagePacket . CommandBlockBlock block = pmc . CommandBlock ;
OnParcelMediaCommand ( new ParcelMediaCommandEventArgs ( simulator , pmc . Header . Sequence , ( ParcelFlags ) block . Flags ,
( ParcelMediaCommand ) block . Command , block . Time ) ) ;
2009-07-10 01:48:42 +00:00
}
2007-04-11 04:46:25 +00:00
#endregion Packet Handlers
2006-10-21 02:52:28 +00:00
}
2009-10-17 05:50:51 +00:00
#region EventArgs classes
/// <summary>Contains a parcels dwell data returned from the simulator in response to an <see cref="RequestParcelDwell"/></summary>
public class ParcelDwellReplyEventArgs : EventArgs
{
/// <summary>Get the global ID of the parcel</summary>
2021-12-09 14:21:48 -06:00
public UUID ParcelID { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the simulator specific ID of the parcel</summary>
2021-12-09 14:21:48 -06:00
public int LocalID { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the calculated dwell</summary>
2021-12-09 14:21:48 -06:00
public float Dwell { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelDwellReplyEventArgs class
/// </summary>
/// <param name="parcelID">The global ID of the parcel</param>
/// <param name="localID">The simulator specific ID of the parcel</param>
/// <param name="dwell">The calculated dwell for the parcel</param>
public ParcelDwellReplyEventArgs ( UUID parcelID , int localID , float dwell )
{
2021-12-09 14:21:48 -06:00
ParcelID = parcelID ;
LocalID = localID ;
Dwell = dwell ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains basic parcel information data returned from the
/// simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
public class ParcelInfoReplyEventArgs : EventArgs
2021-12-09 14:21:48 -06:00
{
2009-10-17 05:50:51 +00:00
/// <summary>Get the <see cref="ParcelInfo"/> object containing basic parcel info</summary>
2021-12-09 14:21:48 -06:00
public ParcelInfo Parcel { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelInfoReplyEventArgs class
/// </summary>
/// <param name="parcel">The <see cref="ParcelInfo"/> object containing basic parcel info</param>
public ParcelInfoReplyEventArgs ( ParcelInfo parcel )
{
2021-12-09 14:21:48 -06:00
Parcel = parcel ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains basic parcel information data returned from the simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
public class ParcelPropertiesEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel is located in</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the <see cref="Parcel"/> object containing the details</summary>
/// <remarks>If Result is NoData, this object will not contain valid data</remarks>
2021-12-09 14:21:48 -06:00
public Parcel Parcel { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the result of the request</summary>
2021-12-09 14:21:48 -06:00
public ParcelResult Result { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the number of primitieves your agent is
/// currently selecting and or sitting on in this parcel</summary>
2021-12-09 14:21:48 -06:00
public int SelectedPrims { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the user assigned ID used to correlate a request with
/// these results</summary>
2021-12-09 14:21:48 -06:00
public int SequenceID { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>TODO:</summary>
2021-12-09 14:21:48 -06:00
public bool SnapSelection { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelPropertiesEventArgs class
/// </summary>
/// <param name="simulator">The <see cref="Parcel"/> object containing the details</param>
/// <param name="parcel">The <see cref="Parcel"/> object containing the details</param>
/// <param name="result">The result of the request</param>
/// <param name="selectedPrims">The number of primitieves your agent is
/// currently selecting and or sitting on in this parcel</param>
/// <param name="sequenceID">The user assigned ID used to correlate a request with
/// these results</param>
/// <param name="snapSelection">TODO:</param>
public ParcelPropertiesEventArgs ( Simulator simulator , Parcel parcel , ParcelResult result , int selectedPrims ,
int sequenceID , bool snapSelection )
{
2021-12-09 14:21:48 -06:00
Simulator = simulator ;
Parcel = parcel ;
Result = result ;
SelectedPrims = selectedPrims ;
SequenceID = sequenceID ;
SnapSelection = snapSelection ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains blacklist and whitelist data returned from the simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
public class ParcelAccessListReplyEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel is located in</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the user assigned ID used to correlate a request with
/// these results</summary>
2021-12-09 14:21:48 -06:00
public int SequenceID { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the simulator specific ID of the parcel</summary>
2021-12-09 14:21:48 -06:00
public int LocalID { get ; }
2016-09-25 19:52:04 -05:00
/// <summary>TODO</summary>
2021-12-09 14:21:48 -06:00
public uint Flags { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the list containing the white/blacklisted agents for the parcel</summary>
2021-12-09 14:21:48 -06:00
public List < ParcelManager . ParcelAccessEntry > AccessList { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelAccessListReplyEventArgs class
/// </summary>
/// <param name="simulator">The simulator the parcel is located in</param>
/// <param name="sequenceID">The user assigned ID used to correlate a request with
/// these results</param>
/// <param name="localID">The simulator specific ID of the parcel</param>
/// <param name="flags">TODO:</param>
/// <param name="accessEntries">The list containing the white/blacklisted agents for the parcel</param>
public ParcelAccessListReplyEventArgs ( Simulator simulator , int sequenceID , int localID , uint flags , List < ParcelManager . ParcelAccessEntry > accessEntries )
{
2021-12-09 14:21:48 -06:00
Simulator = simulator ;
SequenceID = sequenceID ;
LocalID = localID ;
Flags = flags ;
AccessList = accessEntries ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains blacklist and whitelist data returned from the
/// simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
public class ParcelObjectOwnersReplyEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel is located in</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the list containing prim ownership counts</summary>
2021-12-09 14:21:48 -06:00
public List < ParcelManager . ParcelPrimOwners > PrimOwners { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelObjectOwnersReplyEventArgs class
/// </summary>
/// <param name="simulator">The simulator the parcel is located in</param>
/// <param name="primOwners">The list containing prim ownership counts</param>
public ParcelObjectOwnersReplyEventArgs ( Simulator simulator , List < ParcelManager . ParcelPrimOwners > primOwners )
{
2021-12-09 14:21:48 -06:00
Simulator = simulator ;
PrimOwners = primOwners ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains the data returned when all parcel data has been retrieved from a simulator</summary>
public class SimParcelsDownloadedEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel data was retrieved from</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>A dictionary containing the parcel data where the key correlates to the ParcelMap entry</summary>
2021-12-09 14:21:48 -06:00
public InternalDictionary < int , Parcel > Parcels { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the multidimensional array containing a x,y grid mapped
/// to each 64x64 parcel's LocalID.</summary>
2021-12-09 14:21:48 -06:00
public int [ , ] ParcelMap { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the SimParcelsDownloadedEventArgs class
/// </summary>
/// <param name="simulator">The simulator the parcel data was retrieved from</param>
/// <param name="simParcels">The dictionary containing the parcel data</param>
/// <param name="parcelMap">The multidimensional array containing a x,y grid mapped
/// to each 64x64 parcel's LocalID.</param>
public SimParcelsDownloadedEventArgs ( Simulator simulator , InternalDictionary < int , Parcel > simParcels , int [ , ] parcelMap )
{
2021-12-09 14:21:48 -06:00
Simulator = simulator ;
Parcels = simParcels ;
ParcelMap = parcelMap ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains the data returned when a <see cref="RequestForceSelectObjects"/> request</summary>
public class ForceSelectObjectsReplyEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel data was retrieved from</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the list of primitive IDs</summary>
2021-12-09 14:21:48 -06:00
public List < uint > ObjectIDs { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>true if the list is clean and contains the information
/// only for a given request</summary>
2021-12-09 14:21:48 -06:00
public bool ResetList { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ForceSelectObjectsReplyEventArgs class
/// </summary>
/// <param name="simulator">The simulator the parcel data was retrieved from</param>
/// <param name="objectIDs">The list of primitive IDs</param>
/// <param name="resetList">true if the list is clean and contains the information
/// only for a given request</param>
public ForceSelectObjectsReplyEventArgs ( Simulator simulator , List < uint > objectIDs , bool resetList )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . ObjectIDs = objectIDs ;
this . ResetList = resetList ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains data when the media data for a parcel the avatar is on changes</summary>
public class ParcelMediaUpdateReplyEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel media data was updated in</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the updated media information</summary>
2021-12-09 14:21:48 -06:00
public ParcelMedia Media { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelMediaUpdateReplyEventArgs class
/// </summary>
/// <param name="simulator">the simulator the parcel media data was updated in</param>
/// <param name="media">The updated media information</param>
public ParcelMediaUpdateReplyEventArgs ( Simulator simulator , ParcelMedia media )
{
2021-12-09 14:21:48 -06:00
this . Simulator = simulator ;
this . Media = media ;
2009-10-17 05:50:51 +00:00
}
}
/// <summary>Contains the media command for a parcel the agent is currently on</summary>
public class ParcelMediaCommandEventArgs : EventArgs
{
/// <summary>Get the simulator the parcel media command was issued in</summary>
2021-12-09 14:21:48 -06:00
public Simulator Simulator { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public uint Sequence { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public ParcelFlags ParcelFlags { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary>Get the media command that was sent</summary>
2021-12-09 14:21:48 -06:00
public ParcelMediaCommand MediaCommand { get ; }
2016-09-25 19:52:04 -05:00
2009-10-17 05:50:51 +00:00
/// <summary></summary>
2021-12-09 14:21:48 -06:00
public float Time { get ; }
2009-10-17 05:50:51 +00:00
/// <summary>
/// Construct a new instance of the ParcelMediaCommandEventArgs class
/// </summary>
/// <param name="simulator">The simulator the parcel media command was issued in</param>
/// <param name="sequence"></param>
/// <param name="flags"></param>
/// <param name="command">The media command that was sent</param>
/// <param name="time"></param>
public ParcelMediaCommandEventArgs ( Simulator simulator , uint sequence , ParcelFlags flags , ParcelMediaCommand command , float time )
{
2021-12-09 14:21:48 -06:00
Simulator = simulator ;
Sequence = sequence ;
ParcelFlags = flags ;
MediaCommand = command ;
Time = time ;
2009-10-17 05:50:51 +00:00
}
}
#endregion
2006-10-21 02:52:28 +00:00
}