2006-10-21 02:52:28 +00:00
/ *
2009-04-13 09:32:25 +00:00
* Copyright ( c ) 2007 - 2009 , openmetaverse . org
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 .
2009-04-13 09:32:25 +00:00
* - Neither the name of the openmetaverse . org 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 ;
using OpenMetaverse.Http ;
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 ;
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 ;
2006-10-21 02:52:28 +00:00
/// <summary></summary>
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 ;
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 ( )
{
string result = "" ;
Type parcelType = this . GetType ( ) ;
FieldInfo [ ] fields = parcelType . GetFields ( ) ;
foreach ( FieldInfo field in fields )
{
result + = ( field . Name + " = " + field . GetValue ( this ) + " " ) ;
}
return result ;
}
2006-10-21 02:52:28 +00:00
/// <summary>
2007-03-19 13:38:10 +00:00
/// Defalt 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 ;
2007-11-29 19:38:32 +00:00
Name = String . Empty ;
Desc = String . Empty ;
2009-04-14 05:32:20 +00:00
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>
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>
2008-09-22 13:02:27 +00:00
public void Update ( Simulator simulator , bool wantReply )
2006-10-21 02:52:28 +00:00
{
2009-01-27 23:06:31 +00:00
Uri url = simulator . Caps . CapabilityURI ( "ParcelPropertiesUpdate" ) ;
if ( url ! = null )
{
2009-04-13 09:32:25 +00:00
ParcelPropertiesUpdateMessage req = new ParcelPropertiesUpdateMessage ( ) ;
req . AuthBuyerID = this . AuthBuyerID ;
req . Category = this . Category ;
req . Desc = this . Desc ;
req . GroupID = this . GroupID ;
req . Landing = this . Landing ;
req . LocalID = this . LocalID ;
req . MediaAutoScale = this . Media . MediaAutoScale ;
req . MediaDesc = this . Media . MediaDesc ;
req . MediaHeight = this . Media . MediaHeight ;
req . MediaID = this . Media . MediaID ;
req . MediaLoop = this . Media . MediaLoop ;
req . MediaType = this . Media . MediaType ;
req . MediaURL = this . Media . MediaURL ;
req . MediaWidth = this . Media . MediaWidth ;
req . MusicURL = this . MusicURL ;
req . Name = this . Name ;
req . ObscureMedia = this . ObscureMedia ;
req . ObscureMusic = this . ObscureMusic ;
req . ParcelFlags = this . Flags ;
req . PassHours = this . PassHours ;
req . PassPrice = ( uint ) this . PassPrice ;
req . SalePrice = ( uint ) this . SalePrice ;
req . SnapshotID = this . SnapshotID ;
req . UserLocation = this . UserLocation ;
req . UserLookAt = this . UserLookAt ;
2009-10-17 05:50:51 +00:00
2009-04-13 09:32:25 +00:00
OSDMap body = req . Serialize ( ) ;
2009-04-10 21:34:59 +00:00
2009-01-27 23:06:31 +00:00
CapsClient capsPost = new CapsClient ( url ) ;
2009-05-01 06:04:32 +00:00
capsPost . BeginGetResponse ( body , OSDFormat . Xml , simulator . Client . Settings . CAPS_TIMEOUT ) ;
2009-01-27 23:06:31 +00:00
}
else
{
ParcelPropertiesUpdatePacket request = new ParcelPropertiesUpdatePacket ( ) ;
request . AgentData . AgentID = simulator . Client . Self . AgentID ;
request . AgentData . SessionID = simulator . Client . Self . SessionID ;
request . ParcelData . LocalID = this . LocalID ;
request . ParcelData . AuthBuyerID = this . AuthBuyerID ;
request . ParcelData . Category = ( byte ) this . Category ;
request . ParcelData . Desc = Utils . StringToBytes ( this . Desc ) ;
request . ParcelData . GroupID = this . GroupID ;
request . ParcelData . LandingType = ( byte ) this . Landing ;
2009-04-10 21:34:59 +00:00
request . ParcelData . MediaAutoScale = ( this . Media . MediaAutoScale ) ? ( byte ) 0x1 : ( byte ) 0x0 ;
2009-01-27 23:06:31 +00:00
request . ParcelData . MediaID = this . Media . MediaID ;
2009-04-14 04:47:55 +00:00
request . ParcelData . MediaURL = Utils . StringToBytes ( this . Media . MediaURL . ToString ( ) ) ;
request . ParcelData . MusicURL = Utils . StringToBytes ( this . MusicURL . ToString ( ) ) ;
2009-01-27 23:06:31 +00:00
request . ParcelData . Name = Utils . StringToBytes ( this . Name ) ;
if ( wantReply ) request . ParcelData . Flags = 1 ;
request . ParcelData . ParcelFlags = ( uint ) this . Flags ;
request . ParcelData . PassHours = this . PassHours ;
request . ParcelData . PassPrice = this . PassPrice ;
request . ParcelData . SalePrice = this . SalePrice ;
request . ParcelData . SnapshotID = this . SnapshotID ;
request . ParcelData . UserLocation = this . UserLocation ;
request . ParcelData . UserLookAt = this . UserLookAt ;
2009-05-22 19:54:00 +00:00
simulator . SendPacket ( request ) ;
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
{
ParcelSetOtherCleanTimePacket request = new ParcelSetOtherCleanTimePacket ( ) ;
2008-09-22 13:02:27 +00:00
request . AgentData . AgentID = simulator . Client . Self . AgentID ;
request . AgentData . SessionID = simulator . Client . Self . SessionID ;
2007-04-11 04:46:25 +00:00
request . ParcelData . LocalID = this . LocalID ;
request . ParcelData . OtherCleanTime = this . OtherCleanTime ;
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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <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 ) ;
2008-10-06 00:38:50 +00:00
Client . Network . RegisterEventCallback ( "ParcelObjectOwnersReply" , new Caps . EventQueueCallback ( ParcelObjectOwnersReplyHandler ) ) ;
2008-03-10 09:19:51 +00:00
// CAPS packet handler, to allow for Media Data not contained in the message template
Client . Network . RegisterEventCallback ( "ParcelProperties" , new Caps . EventQueueCallback ( 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
{
2007-01-19 13:15:12 +00:00
ParcelInfoRequestPacket request = new ParcelInfoRequestPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-01-19 13:15:12 +00:00
request . 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
{
ParcelPropertiesRequestByIDPacket request = new ParcelPropertiesRequestByIDPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . ParcelData . LocalID = localID ;
request . ParcelData . 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
{
ParcelAccessListRequestPacket request = new ParcelAccessListRequestPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-04-10 10:05:25 +00:00
request . Data . LocalID = localID ;
2007-04-11 04:46:25 +00:00
request . Data . Flags = ( uint ) flags ;
2007-04-10 10:05:25 +00:00
request . Data . 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
{
2007-01-19 13:15:12 +00:00
ParcelPropertiesRequestPacket request = new ParcelPropertiesRequestPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-01-19 13:15:12 +00:00
request . ParcelData . North = north ;
request . ParcelData . East = east ;
request . ParcelData . South = south ;
request . ParcelData . West = west ;
request . ParcelData . SequenceID = sequenceID ;
request . ParcelData . SnapSelection = snapSelection ;
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 )
{
2008-05-22 05:35:10 +00:00
for ( int y = 0 ; y < 64 ; y + + )
for ( int x = 0 ; x < 64 ; x + + )
simulator . ParcelMap [ y , x ] = 0 ;
2008-03-07 17:43:51 +00:00
}
2007-12-04 03:59:21 +00:00
Thread th = new Thread ( delegate ( )
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
} ) ;
2008-05-22 05:35:10 +00:00
2007-12-04 03:59:21 +00:00
th . Start ( ) ;
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
{
ParcelDwellRequestPacket request = new ParcelDwellRequestPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . Data . LocalID = localID ;
2008-07-25 05:15:05 +00:00
request . Data . 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
{
ParcelBuyPacket request = new ParcelBuyPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . Data . Final = true ;
request . Data . GroupID = groupID ;
request . Data . LocalID = localID ;
request . Data . IsGroupOwned = forGroup ;
request . Data . RemoveContribution = removeContribution ;
2007-07-18 21:59:13 +00:00
request . ParcelData . Area = parcelArea ;
request . ParcelData . Price = parcelPrice ;
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 )
{
ParcelReclaimPacket request = new ParcelReclaimPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . Data . LocalID = localID ;
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
{
ParcelDeedToGroupPacket request = new ParcelDeedToGroupPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . Data . LocalID = localID ;
request . Data . GroupID = groupID ;
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
{
ParcelObjectOwnersRequestPacket request = new ParcelObjectOwnersRequestPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-08-26 16:52:08 +00:00
request . ParcelData . LocalID = localID ;
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
{
ParcelReturnObjectsPacket request = new ParcelReturnObjectsPacket ( ) ;
2007-11-06 09:26:10 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-03-19 13:38:10 +00:00
request . ParcelData . LocalID = localID ;
request . ParcelData . ReturnType = ( uint ) type ;
// A single null TaskID is (not) used for parcel object returns
request . TaskIDs = new ParcelReturnObjectsPacket . TaskIDsBlock [ 1 ] ;
request . TaskIDs [ 0 ] = new ParcelReturnObjectsPacket . TaskIDsBlock ( ) ;
2008-07-25 05:15:05 +00:00
request . TaskIDs [ 0 ] . 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 + + )
{
request . OwnerIDs [ i ] = new ParcelReturnObjectsPacket . OwnerIDsBlock ( ) ;
request . OwnerIDs [ i ] . OwnerID = ownerIDs [ i ] ;
}
}
else
{
request . OwnerIDs = new ParcelReturnObjectsPacket . OwnerIDsBlock [ 0 ] ;
}
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 )
{
ParcelDividePacket divide = new ParcelDividePacket ( ) ;
2007-11-06 09:26:10 +00:00
divide . AgentData . AgentID = Client . Self . AgentID ;
divide . AgentData . SessionID = Client . Self . SessionID ;
2007-07-13 14:49:36 +00:00
divide . ParcelData . East = east ;
divide . ParcelData . North = north ;
divide . ParcelData . South = south ;
divide . ParcelData . West = west ;
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 )
{
ModifyLandPacket land = new ModifyLandPacket ( ) ;
land . AgentData . AgentID = Client . Self . AgentID ;
land . AgentData . SessionID = Client . Self . SessionID ;
land . ModifyBlock . Action = ( byte ) action ;
land . ModifyBlock . BrushSize = ( byte ) brushSize ;
land . ModifyBlock . Seconds = seconds ;
land . ModifyBlock . Height = height ;
2008-09-06 10:19:46 +00:00
land . ParcelData = new ModifyLandPacket . ParcelDataBlock [ 1 ] ;
land . ParcelData [ 0 ] = new ModifyLandPacket . ParcelDataBlock ( ) ;
2007-12-22 21:50:42 +00:00
land . ParcelData [ 0 ] . LocalID = localID ;
land . ParcelData [ 0 ] . West = west ;
land . ParcelData [ 0 ] . South = south ;
land . ParcelData [ 0 ] . East = east ;
land . ParcelData [ 0 ] . North = north ;
2010-06-29 12:41:12 +00:00
land . ModifyBlockExtended = new ModifyLandPacket . ModifyBlockExtendedBlock [ 1 ] ;
land . ModifyBlockExtended [ 0 ] = new ModifyLandPacket . ModifyBlockExtendedBlock ( ) ;
land . ModifyBlockExtended [ 0 ] . BrushSize = ( float ) brushSize ;
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 ] ;
select . ReturnIDs [ 0 ] = new ParcelSelectObjectsPacket . ReturnIDsBlock ( ) ;
select . ReturnIDs [ 0 ] . ReturnID = ownerID ;
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
{
EjectUserPacket eject = new EjectUserPacket ( ) ;
eject . AgentData . AgentID = Client . Self . AgentID ;
eject . AgentData . SessionID = Client . Self . SessionID ;
eject . Data . TargetID = targetID ;
if ( ban ) eject . Data . Flags = 1 ;
else eject . Data . Flags = 0 ;
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
{
FreezeUserPacket frz = new FreezeUserPacket ( ) ;
frz . AgentData . AgentID = Client . Self . AgentID ;
frz . AgentData . SessionID = Client . Self . SessionID ;
frz . Data . TargetID = targetID ;
if ( freeze ) frz . Data . Flags = 0 ;
else frz . Data . Flags = 1 ;
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 )
{
ParcelReleasePacket abandon = new ParcelReleasePacket ( ) ;
abandon . AgentData . AgentID = Client . Self . AgentID ;
abandon . AgentData . SessionID = Client . Self . SessionID ;
abandon . Data . LocalID = localID ;
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>
public UUID RequestRemoteParcelID ( Vector3 location , ulong regionHandle , UUID regionID )
{
2011-12-03 17:14:53 +00:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
return UUID . Zero ;
2009-06-26 06:51:41 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "RemoteParcelRequest" ) ;
if ( url ! = null )
{
2009-06-27 23:07:04 +00:00
RemoteParcelRequestRequest msg = new RemoteParcelRequestRequest ( ) ;
2009-06-26 06:51:41 +00:00
msg . Location = location ;
msg . RegionHandle = regionHandle ;
msg . RegionID = regionID ;
try
{
CapsClient request = new CapsClient ( url ) ;
OSD result = request . GetResponse ( msg . Serialize ( ) , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2009-06-27 23:07:04 +00:00
RemoteParcelRequestReply response = new RemoteParcelRequestReply ( ) ;
2009-06-26 06:51:41 +00:00
response . Deserialize ( ( OSDMap ) result ) ;
return response . ParcelID ;
}
catch ( Exception )
{
Logger . Log ( "Failed to fetch remote parcel ID" , Helpers . LogLevel . Debug , Client ) ;
}
}
return UUID . Zero ;
}
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>
public void GetParcelResouces ( UUID parcelID , bool getDetails , LandResourcesCallback callback )
{
try
{
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "LandResources" ) ;
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = delegate ( CapsClient client , OSD result , Exception error )
{
try
{
if ( result = = null | | error ! = null )
{
callback ( false , null ) ;
}
LandResourcesMessage response = new LandResourcesMessage ( ) ;
response . Deserialize ( ( OSDMap ) result ) ;
CapsClient summaryRequest = new CapsClient ( response . ScriptResourceSummary ) ;
OSD summaryResponse = summaryRequest . GetResponse ( Client . Settings . CAPS_TIMEOUT ) ;
LandResourcesInfo res = new LandResourcesInfo ( ) ;
res . Deserialize ( ( OSDMap ) summaryResponse ) ;
if ( response . ScriptResourceDetails ! = null & & getDetails )
{
CapsClient detailRequest = new CapsClient ( response . ScriptResourceDetails ) ;
OSD detailResponse = detailRequest . GetResponse ( Client . Settings . CAPS_TIMEOUT ) ;
res . Deserialize ( ( OSDMap ) detailResponse ) ;
}
callback ( true , res ) ;
}
catch ( Exception ex )
{
Logger . Log ( "Failed fetching land resources" , Helpers . LogLevel . Error , Client , ex ) ;
callback ( false , null ) ;
}
} ;
LandResourcesRequest param = new LandResourcesRequest ( ) ;
param . ParcelID = parcelID ;
request . BeginGetResponse ( param . Serialize ( ) , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
}
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
{
if ( m_DwellReply ! = null | | Client . Settings . ALWAYS_REQUEST_PARCEL_DWELL = = true )
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 )
2009-10-17 05:50:51 +00:00
{
if ( m_ParcelInfo ! = null )
2006-10-21 02:52:28 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2007-01-19 13:15:12 +00:00
ParcelInfoReplyPacket info = ( ParcelInfoReplyPacket ) packet ;
ParcelInfo parcelInfo = new ParcelInfo ( ) ;
parcelInfo . ActualArea = info . Data . ActualArea ;
parcelInfo . AuctionID = info . Data . AuctionID ;
parcelInfo . BillableArea = info . Data . BillableArea ;
2008-08-12 22:38:02 +00:00
parcelInfo . Description = Utils . BytesToString ( info . Data . Desc ) ;
2007-01-19 13:15:12 +00:00
parcelInfo . Dwell = info . Data . Dwell ;
parcelInfo . GlobalX = info . Data . GlobalX ;
parcelInfo . GlobalY = info . Data . GlobalY ;
parcelInfo . GlobalZ = info . Data . GlobalZ ;
parcelInfo . ID = info . Data . ParcelID ;
parcelInfo . Mature = ( ( info . Data . Flags & 1 ) ! = 0 ) ? true : false ;
2008-08-12 22:38:02 +00:00
parcelInfo . Name = Utils . BytesToString ( info . Data . Name ) ;
2007-01-19 13:15:12 +00:00
parcelInfo . OwnerID = info . Data . OwnerID ;
parcelInfo . SalePrice = info . Data . SalePrice ;
2008-08-12 22:38:02 +00:00
parcelInfo . SimName = Utils . BytesToString ( info . Data . SimName ) ;
2007-01-19 13:15:12 +00:00
parcelInfo . SnapshotID = info . Data . SnapshotID ;
2009-10-17 05:50:51 +00:00
OnParcelInfoReply ( new ParcelInfoReplyEventArgs ( parcelInfo ) ) ;
2006-10-27 21:42:23 +00:00
}
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 )
{
if ( m_ParcelProperties ! = null | | Client . Settings . PARCEL_TRACKING = = true )
2009-04-10 21:34:59 +00:00
{
2009-04-13 09:32:25 +00:00
ParcelPropertiesMessage msg = ( ParcelPropertiesMessage ) message ;
Parcel parcel = new Parcel ( msg . LocalID ) ;
parcel . AABBMax = msg . AABBMax ;
parcel . AABBMin = msg . AABBMin ;
parcel . Area = msg . Area ;
parcel . AuctionID = msg . AuctionID ;
parcel . AuthBuyerID = msg . AuthBuyerID ;
parcel . Bitmap = msg . Bitmap ;
parcel . Category = msg . Category ;
parcel . ClaimDate = msg . ClaimDate ;
parcel . ClaimPrice = msg . ClaimPrice ;
parcel . Desc = msg . Desc ;
parcel . Flags = msg . ParcelFlags ;
parcel . GroupID = msg . GroupID ;
parcel . GroupPrims = msg . GroupPrims ;
parcel . IsGroupOwned = msg . IsGroupOwned ;
parcel . Landing = msg . LandingType ;
parcel . MaxPrims = msg . MaxPrims ;
parcel . Media . MediaAutoScale = msg . MediaAutoScale ;
parcel . Media . MediaID = msg . MediaID ;
parcel . Media . MediaURL = msg . MediaURL ;
parcel . MusicURL = msg . MusicURL ;
parcel . Name = msg . Name ;
parcel . OtherCleanTime = msg . OtherCleanTime ;
parcel . OtherCount = msg . OtherCount ;
parcel . OtherPrims = msg . OtherPrims ;
parcel . OwnerID = msg . OwnerID ;
parcel . OwnerPrims = msg . OwnerPrims ;
parcel . ParcelPrimBonus = msg . ParcelPrimBonus ;
parcel . PassHours = msg . PassHours ;
parcel . PassPrice = msg . PassPrice ;
parcel . PublicCount = msg . PublicCount ;
parcel . RegionDenyAgeUnverified = msg . RegionDenyAgeUnverified ;
parcel . RegionDenyAnonymous = msg . RegionDenyAnonymous ;
parcel . RegionPushOverride = msg . RegionPushOverride ;
parcel . RentPrice = msg . RentPrice ;
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 ;
2008-03-11 08:15:15 +00:00
2008-03-10 09:19:51 +00:00
if ( Client . Settings . PARCEL_TRACKING )
{
lock ( simulator . Parcels . Dictionary )
simulator . Parcels . Dictionary [ parcel . LocalID ] = parcel ;
2008-12-05 01:34:24 +00:00
bool set = false ;
2008-03-10 09:19:51 +00:00
int y , x , index , bit ;
2008-12-05 01:34:24 +00:00
for ( y = 0 ; y < 64 ; y + + )
2008-03-10 09:19:51 +00:00
{
2008-12-05 01:34:24 +00:00
for ( x = 0 ; x < 64 ; x + + )
2008-03-10 09:19:51 +00:00
{
2008-12-05 01:34:24 +00:00
index = ( y * 64 ) + x ;
bit = index % 8 ;
index > > = 3 ;
2008-03-10 09:19:51 +00:00
2008-12-05 01:34:24 +00:00
if ( ( parcel . Bitmap [ index ] & ( 1 < < bit ) ) ! = 0 )
{
simulator . ParcelMap [ y , x ] = parcel . LocalID ;
set = true ;
2008-03-10 09:19:51 +00:00
}
}
}
2008-12-05 01:34:24 +00: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
}
2008-12-05 01:34:24 +00:00
if ( sequenceID . Equals ( int . MaxValue ) & & WaitForSimParcel ! = null )
WaitForSimParcel . Set ( ) ;
2008-03-10 09:19:51 +00:00
// auto request acl, will be stored in parcel tracking dictionary if enabled
if ( Client . Settings . ALWAYS_REQUEST_PARCEL_ACL )
2009-10-17 05:50:51 +00:00
Client . Parcels . RequestParcelAccessList ( simulator , parcel . LocalID ,
2008-09-22 13:02:27 +00:00
AccessList . Both , sequenceID ) ;
2008-03-10 09:19:51 +00:00
// auto request dwell, will be stored in parcel tracking dictionary if enables
if ( Client . Settings . ALWAYS_REQUEST_PARCEL_DWELL )
2009-10-17 05:50:51 +00:00
Client . Parcels . RequestDwell ( simulator , parcel . LocalID ) ;
2008-03-10 09:19:51 +00:00
// Fire the callback for parcel properties being received
2009-10-17 05:50:51 +00:00
if ( m_ParcelProperties ! = null )
2008-03-10 09:19:51 +00:00
{
2009-10-17 05:50:51 +00:00
OnParcelProperties ( new ParcelPropertiesEventArgs ( simulator , parcel , result , selectedPrims , sequenceID , snapSelection ) ) ;
2008-03-10 09:19:51 +00:00
}
// Check if all of the simulator parcels have been retrieved, if so fire another callback
2009-10-17 05:50:51 +00:00
if ( simulator . IsParcelMapFull ( ) & & m_SimParcelsDownloaded ! = null )
2008-03-10 09:19:51 +00:00
{
2009-10-17 05:50:51 +00:00
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
{
2009-10-17 05:50:51 +00:00
if ( m_ParcelACL ! = null | | Client . Settings . ALWAYS_REQUEST_PARCEL_ACL = = true )
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 ) ;
for ( int i = 0 ; i < reply . List . Length ; i + + )
{
ParcelAccessEntry pae = new ParcelAccessEntry ( ) ;
pae . AgentID = reply . List [ i ] . ID ;
pae . Time = Utils . UnixTimeToDateTime ( ( uint ) reply . List [ i ] . Time ) ;
2008-11-17 20:29:13 +00:00
pae . Flags = ( AccessList ) reply . List [ i ] . 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
2009-04-25 01:54:52 +00:00
for ( int i = 0 ; i < msg . PrimOwnersBlock . Length ; i + + )
2008-10-06 01:12:05 +00:00
{
2009-04-10 21:34:59 +00:00
ParcelPrimOwners primOwner = new ParcelPrimOwners ( ) ;
2009-04-25 01:54:52 +00:00
primOwner . OwnerID = msg . PrimOwnersBlock [ i ] . OwnerID ;
primOwner . Count = msg . PrimOwnersBlock [ i ] . Count ;
primOwner . IsGroupOwned = msg . PrimOwnersBlock [ i ] . IsGroupOwned ;
primOwner . OnlineStatus = msg . PrimOwnersBlock [ i ] . OnlineStatus ;
primOwner . NewestPrim = msg . PrimOwnersBlock [ i ] . 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
{
2009-10-17 05:50:51 +00:00
if ( m_ForceSelectObjects ! = null )
2008-01-12 07:19:30 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-17 05:50:51 +00:00
ForceObjectSelectPacket reply = ( ForceObjectSelectPacket ) packet ;
List < uint > objectIDs = new List < uint > ( reply . Data . Length ) ;
2008-01-12 07:19:30 +00:00
2009-10-17 05:50:51 +00:00
for ( int i = 0 ; i < reply . Data . Length ; i + + )
{
objectIDs . Add ( reply . Data [ i ] . LocalID ) ;
}
OnForceSelectObjectsReply ( new ForceSelectObjectsReplyEventArgs ( simulator , objectIDs , reply . _Header . ResetList ) ) ;
2008-07-24 18:48:37 +00:00
}
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
{
2009-10-17 05:50:51 +00:00
if ( m_ParcelMediaUpdateReply ! = null )
2008-07-26 08:50:37 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-17 05:50:51 +00:00
ParcelMediaUpdatePacket reply = ( ParcelMediaUpdatePacket ) packet ;
ParcelMedia media = new ParcelMedia ( ) ;
media . MediaAutoScale = ( reply . DataBlock . MediaAutoScale = = ( byte ) 0x1 ) ? true : false ;
media . MediaID = reply . DataBlock . MediaID ;
media . MediaDesc = Utils . BytesToString ( reply . DataBlockExtended . MediaDesc ) ;
media . MediaHeight = reply . DataBlockExtended . MediaHeight ;
media . MediaLoop = ( ( reply . DataBlockExtended . MediaLoop & 1 ) ! = 0 ) ? true : false ;
media . MediaType = Utils . BytesToString ( reply . DataBlockExtended . MediaType ) ;
media . MediaWidth = reply . DataBlockExtended . MediaWidth ;
media . MediaURL = Utils . BytesToString ( reply . DataBlock . MediaURL ) ;
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 +
" received from " + simulator . ToString ( ) , Helpers . LogLevel . Warning , Client ) ;
}
}
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
{
2009-10-17 05:50:51 +00:00
if ( m_ParcelMediaCommand ! = null )
2009-07-10 01:48:42 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-07-10 01:48:42 +00:00
ParcelMediaCommandMessagePacket pmc = ( ParcelMediaCommandMessagePacket ) packet ;
ParcelMediaCommandMessagePacket . CommandBlockBlock block = pmc . CommandBlock ;
2009-10-17 05:50:51 +00:00
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
{
private readonly UUID m_ParcelID ;
private readonly int m_LocalID ;
private readonly float m_Dwell ;
/// <summary>Get the global ID of the parcel</summary>
public UUID ParcelID { get { return m_ParcelID ; } }
/// <summary>Get the simulator specific ID of the parcel</summary>
public int LocalID { get { return m_LocalID ; } }
/// <summary>Get the calculated dwell</summary>
public float Dwell { get { return m_Dwell ; } }
/// <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 )
{
this . m_ParcelID = parcelID ;
this . m_LocalID = localID ;
this . m_Dwell = dwell ;
}
}
/// <summary>Contains basic parcel information data returned from the
/// simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
public class ParcelInfoReplyEventArgs : EventArgs
{
private readonly ParcelInfo m_Parcel ;
/// <summary>Get the <see cref="ParcelInfo"/> object containing basic parcel info</summary>
public ParcelInfo Parcel { get { return m_Parcel ; } }
/// <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 )
{
this . m_Parcel = parcel ;
}
}
/// <summary>Contains basic parcel information data returned from the simulator in response to an <see cref="RequestParcelInfo"/> request</summary>
public class ParcelPropertiesEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private Parcel m_Parcel ;
private readonly ParcelResult m_Result ;
private readonly int m_SelectedPrims ;
private readonly int m_SequenceID ;
private readonly bool m_SnapSelection ;
/// <summary>Get the simulator the parcel is located in</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the <see cref="Parcel"/> object containing the details</summary>
/// <remarks>If Result is NoData, this object will not contain valid data</remarks>
public Parcel Parcel { get { return m_Parcel ; } }
/// <summary>Get the result of the request</summary>
public ParcelResult Result { get { return m_Result ; } }
/// <summary>Get the number of primitieves your agent is
/// currently selecting and or sitting on in this parcel</summary>
public int SelectedPrims { get { return m_SelectedPrims ; } }
/// <summary>Get the user assigned ID used to correlate a request with
/// these results</summary>
public int SequenceID { get { return m_SequenceID ; } }
/// <summary>TODO:</summary>
public bool SnapSelection { get { return m_SnapSelection ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_Parcel = parcel ;
this . m_Result = result ;
this . m_SelectedPrims = selectedPrims ;
this . m_SequenceID = sequenceID ;
this . m_SnapSelection = snapSelection ;
}
}
/// <summary>Contains blacklist and whitelist data returned from the simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
public class ParcelAccessListReplyEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly int m_SequenceID ;
private readonly int m_LocalID ;
private readonly uint m_Flags ;
private readonly List < ParcelManager . ParcelAccessEntry > m_AccessList ;
/// <summary>Get the simulator the parcel is located in</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the user assigned ID used to correlate a request with
/// these results</summary>
public int SequenceID { get { return m_SequenceID ; } }
/// <summary>Get the simulator specific ID of the parcel</summary>
public int LocalID { get { return m_LocalID ; } }
/// <summary>TODO:</summary>
public uint Flags { get { return m_Flags ; } }
/// <summary>Get the list containing the white/blacklisted agents for the parcel</summary>
public List < ParcelManager . ParcelAccessEntry > AccessList { get { return m_AccessList ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_SequenceID = sequenceID ;
this . m_LocalID = localID ;
this . m_Flags = flags ;
this . m_AccessList = accessEntries ;
}
}
/// <summary>Contains blacklist and whitelist data returned from the
/// simulator in response to an <see cref="RequestParcelAccesslist"/> request</summary>
public class ParcelObjectOwnersReplyEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly List < ParcelManager . ParcelPrimOwners > m_Owners ;
/// <summary>Get the simulator the parcel is located in</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the list containing prim ownership counts</summary>
public List < ParcelManager . ParcelPrimOwners > PrimOwners { get { return m_Owners ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_Owners = primOwners ;
}
}
/// <summary>Contains the data returned when all parcel data has been retrieved from a simulator</summary>
public class SimParcelsDownloadedEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly InternalDictionary < int , Parcel > m_Parcels ;
private readonly int [ , ] m_ParcelMap ;
/// <summary>Get the simulator the parcel data was retrieved from</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>A dictionary containing the parcel data where the key correlates to the ParcelMap entry</summary>
public InternalDictionary < int , Parcel > Parcels { get { return m_Parcels ; } }
/// <summary>Get the multidimensional array containing a x,y grid mapped
/// to each 64x64 parcel's LocalID.</summary>
public int [ , ] ParcelMap { get { return m_ParcelMap ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_Parcels = simParcels ;
this . m_ParcelMap = parcelMap ;
}
}
/// <summary>Contains the data returned when a <see cref="RequestForceSelectObjects"/> request</summary>
public class ForceSelectObjectsReplyEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly List < uint > m_ObjectIDs ;
private readonly bool m_ResetList ;
/// <summary>Get the simulator the parcel data was retrieved from</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the list of primitive IDs</summary>
public List < uint > ObjectIDs { get { return m_ObjectIDs ; } }
/// <summary>true if the list is clean and contains the information
/// only for a given request</summary>
public bool ResetList { get { return m_ResetList ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_ObjectIDs = objectIDs ;
this . m_ResetList = resetList ;
}
}
/// <summary>Contains data when the media data for a parcel the avatar is on changes</summary>
public class ParcelMediaUpdateReplyEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly ParcelMedia m_ParcelMedia ;
/// <summary>Get the simulator the parcel media data was updated in</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary>Get the updated media information</summary>
public ParcelMedia Media { get { return m_ParcelMedia ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_ParcelMedia = media ;
}
}
/// <summary>Contains the media command for a parcel the agent is currently on</summary>
public class ParcelMediaCommandEventArgs : EventArgs
{
private readonly Simulator m_Simulator ;
private readonly uint m_Sequence ;
private readonly ParcelFlags m_ParcelFlags ;
private readonly ParcelMediaCommand m_MediaCommand ;
private readonly float m_Time ;
/// <summary>Get the simulator the parcel media command was issued in</summary>
public Simulator Simulator { get { return m_Simulator ; } }
/// <summary></summary>
public uint Sequence { get { return m_Sequence ; } }
/// <summary></summary>
public ParcelFlags ParcelFlags { get { return m_ParcelFlags ; } }
/// <summary>Get the media command that was sent</summary>
public ParcelMediaCommand MediaCommand { get { return m_MediaCommand ; } }
/// <summary></summary>
public float Time { get { return m_Time ; } }
/// <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 )
{
this . m_Simulator = simulator ;
this . m_Sequence = sequence ;
this . m_ParcelFlags = flags ;
this . m_MediaCommand = command ;
this . m_Time = time ;
}
}
#endregion
2006-10-21 02:52:28 +00:00
}