Files
libremetaverse/libsecondlife/ParcelManager.cs
John Hurliman 1cb7f4c253 Huge svn cleanup!
* libsecondlife-cs is now libsecondlife
* All applications that are staying have been moved to trunk/
* SLProxy loads Analyst plugin by default if no other plugin is specified on the command line

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1068 52acb1d6-8a22-11de-b505-999d5b087335
2007-03-26 23:12:39 +00:00

792 lines
33 KiB
C#

/*
* Copyright (c) 2006, Second Life Reverse Engineering Team
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* 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.
* - Neither the name of the Second Life Reverse Engineering Team nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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
* POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Timers;
using System.Collections.Generic;
using libsecondlife.Packets;
namespace libsecondlife
{
/// <summary>
/// Parcel of land, a portion of virtual real estate in a simulator
/// </summary>
public class Parcel
{
/// <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></summary>
AllowTerraform = 1 << 4,
/// <summary>Avatars have health and can take damage on this parcel</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>Unknown</summary>
AllowDeedToGroup = 1 << 13,
/// <summary>Unknown</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</summary>
DenyIdentified = 1 << 23,
/// <summary>Ban all transacted avatars</summary>
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>
AllowAllObjectEntry = 1 << 27,
/// <summary>Only allow group and owner objects to enter this parcel</summary>
AllowGroupObjectEntry = 1 << 28,
}
/// <summary>
/// Parcel ownership status
/// </summary>
public enum ParcelStatus : sbyte
{
/// <summary></summary>
None = -1,
/// <summary></summary>
Leased = 0,
/// <summary></summary>
LeasePending = 1,
/// <summary></summary>
Abandoned = 2
}
/// <summary>
///
/// </summary>
public enum ParcelCategory : sbyte
{
/// <summary>No assigned category</summary>
None = 0,
/// <summary></summary>
Linden,
/// <summary></summary>
Adult,
/// <summary></summary>
Arts,
/// <summary></summary>
Business,
/// <summary></summary>
Educational,
/// <summary></summary>
Gaming,
/// <summary></summary>
Hangout,
/// <summary></summary>
Newcomer,
/// <summary></summary>
Park,
/// <summary></summary>
Residential,
/// <summary></summary>
Shopping,
/// <summary></summary>
Stage,
/// <summary></summary>
Other,
/// <summary>Not an actual category, only used for queries</summary>
Any = -1
}
/// <summary></summary>
public int RequestResult;
/// <summary></summary>
public int SequenceID;
/// <summary></summary>
public bool SnapSelection;
/// <summary></summary>
public int SelfCount;
/// <summary></summary>
public int OtherCount;
/// <summary></summary>
public int PublicCount;
/// <summary>Simulator-local ID of this parcel</summary>
public int LocalID { get { return localid; } }
/// <summary>UUID of the owner of this parcel</summary>
public LLUUID OwnerID;
/// <summary>Whether the land is deeded to a group or not</summary>
public bool IsGroupOwned;
/// <summary></summary>
public uint AuctionID;
/// <summary>Reserved for the now defunct First Land program</summary>
public bool ReservedNewbie;
/// <summary>Date land was claimed</summary>
public DateTime ClaimDate;
/// <summary>Appears to always be zero</summary>
public int ClaimPrice;
/// <summary></summary>
public int RentPrice;
/// <summary>Minimum corner of the axis-aligned bounding box for this
/// parcel</summary>
public LLVector3 AABBMin;
/// <summary>Maximum corner of the axis-aligned bounding box for this
/// parcel</summary>
public LLVector3 AABBMax;
/// <summary>Bitmap describing land layout in 4x4m squares across the
/// entire region</summary>
public byte[] Bitmap;
/// <summary>Total parcel land area</summary>
public int Area;
/// <summary></summary>
public ParcelStatus Status;
/// <summary>Maximum primitives across the entire simulator</summary>
public int SimWideMaxPrims;
/// <summary>Total primitives across the entire simulator</summary>
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;
/// <summary>Total number of primitives owned by the parcel owner on
/// this parcel</summary>
public int OwnerPrims;
/// <summary>Total number of primitives owned by the parcel group on
/// this parcel</summary>
public int GroupPrims;
/// <summary>Total number of other primitives on this parcel</summary>
public int OtherPrims;
/// <summary>Total number of primitives you are currently selecting and
/// sitting on</summary>
public int SelectedPrims;
/// <summary></summary>
public float ParcelPrimBonus;
/// <summary></summary>
public int OtherCleanTime;
/// <summary></summary>
public ParcelFlags Flags;
/// <summary></summary>
public int SalePrice;
/// <summary>Parcel Name</summary>
public string Name;
/// <summary>Parcel Description</summary>
public string Desc;
/// <summary>URL For Music Stream</summary>
public string MusicURL;
/// <summary>URL For other Media</summary>
public string MediaURL;
/// <summary>Key to Picture for Media Placeholder</summary>
public LLUUID MediaID;
/// <summary></summary>
public byte MediaAutoScale;
/// <summary></summary>
public LLUUID GroupID;
/// <summary>Price for a temporary pass</summary>
public int PassPrice;
/// <summary>How long is pass valid for</summary>
public float PassHours;
/// <summary></summary>
public ParcelCategory Category;
/// <summary>Key of authorized buyer</summary>
public LLUUID AuthBuyerID;
/// <summary>Key of parcel snapshot</summary>
public LLUUID SnapshotID;
/// <summary></summary>
public LLVector3 UserLocation;
/// <summary></summary>
public LLVector3 UserLookAt;
/// <summary></summary>
public byte LandingType;
/// <summary></summary>
public float Dwell;
/// <summary></summary>
public bool RegionDenyAnonymous;
/// <summary></summary>
public bool RegionDenyIdentified;
/// <summary></summary>
public bool RegionDenyTransacted;
/// <summary></summary>
public bool RegionPushOverride;
/// <summary></summary>
public Simulator Simulator;
private int localid;
/// <summary>
/// Defalt constructor
/// </summary>
/// <param name="simulator">Simulator this parcel resides in</param>
/// <param name="localID">Local ID of this parcel</param>
public Parcel(Simulator simulator, int localID)
{
Simulator = simulator;
localid = localID;
}
/// <summary>
/// Update the simulator with any local changes to this Parcel object
/// </summary>
public void Update()
{
ParcelPropertiesUpdatePacket request = new ParcelPropertiesUpdatePacket();
request.AgentData.AgentID = Simulator.Client.Network.AgentID;
request.AgentData.SessionID = Simulator.Client.Network.SessionID;
request.ParcelData.LocalID = this.LocalID;
request.ParcelData.AuthBuyerID = this.AuthBuyerID;
request.ParcelData.Category = (byte)this.Category;
request.ParcelData.Desc = Helpers.StringToField(this.Desc);
request.ParcelData.GroupID = this.GroupID;
request.ParcelData.LandingType = this.LandingType;
request.ParcelData.MediaAutoScale = this.MediaAutoScale;
request.ParcelData.MediaID = this.MediaID;
request.ParcelData.MediaURL = Helpers.StringToField(this.MediaURL);
request.ParcelData.MusicURL = Helpers.StringToField(this.MusicURL);
request.ParcelData.Name = Helpers.StringToField(this.Name);
request.ParcelData.Flags = (uint)this.Flags;
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;
Simulator.Client.Network.SendPacket(request, Simulator);
}
}
/// <summary>
/// Some information about a parcel of land
/// </summary>
public struct ParcelInfo
{
/// <summary></summary>
public LLUUID ID;
/// <summary></summary>
public LLUUID OwnerID;
/// <summary></summary>
public string Name;
/// <summary></summary>
public string Description;
/// <summary></summary>
public int ActualArea;
/// <summary></summary>
public int BillableArea;
/// <summary></summary>
public bool Mature;
/// <summary></summary>
public float GlobalX;
/// <summary></summary>
public float GlobalY;
/// <summary></summary>
public float GlobalZ;
/// <summary></summary>
public string SimName;
/// <summary></summary>
public LLUUID SnapshotID;
/// <summary></summary>
public float Dwell;
/// <summary></summary>
public int SalePrice;
/// <summary></summary>
public int AuctionID;
}
/// <summary>
/// Parcel (subdivided simulator lots) subsystem
/// </summary>
public class ParcelManager
{
/// <summary>
/// Type of return to use when returning objects from a parcel
/// </summary>
public enum ObjectReturnType : uint
{
/// <summary></summary>
None = 0,
/// <summary></summary>
Owner = 1 << 1,
/// <summary></summary>
Group = 1 << 2,
/// <summary></summary>
Other = 1 << 3,
/// <summary></summary>
List = 1 << 4,
/// <summary></summary>
Sell = 1 << 5
}
/// <summary>
///
/// </summary>
public enum ParcelAccessFlags : uint
{
/// <summary></summary>
NoAccess = 0,
/// <summary></summary>
Access = 1
}
/// <summary>
///
/// </summary>
public struct ParcelAccessEntry
{
/// <summary></summary>
public LLUUID AgentID;
/// <summary></summary>
public int Time;
/// <summary></summary>
public uint Flags;
}
/// <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>
///
/// </summary>
/// <param name="parcelID">UUID of the requested parcel</param>
/// <param name="localID">Simulator-local ID of the requested parcel</param>
/// <param name="dwell">Dwell value of the requested parcel</param>
public delegate void ParcelDwellCallback(LLUUID parcelID, int localID, float dwell);
/// <summary>
///
/// </summary>
/// <param name="parcel"></param>
public delegate void ParcelInfoCallback(ParcelInfo parcel);
/// <summary>
///
/// </summary>
/// <param name="parcel">Full properties for a single parcel. If result
/// is NoData this will be incomplete or incorrect data</param>
/// <param name="result">Success of the query</param>
/// <param name="sequenceID">User-assigned identifier for the query</param>
/// <param name="snapSelection">User-assigned boolean for the query</param>
public delegate void ParcelPropertiesCallback(Parcel parcel, ParcelResult result, int sequenceID, bool snapSelection);
/// <summary>
///
/// </summary>
/// <param name="sequenceID"></param>
/// <param name="localID"></param>
/// <param name="flags"></param>
/// <param name="accessEntries"></param>
public delegate void ParcelAccessListReplyCallback(int sequenceID, int localID, uint flags, List<ParcelAccessEntry> accessEntries);
/// <summary></summary>
public event ParcelDwellCallback OnParcelDwell;
/// <summary></summary>
public event ParcelInfoCallback OnParcelInfo;
/// <summary></summary>
public event ParcelPropertiesCallback OnParcelProperties;
/// <summary></summary>
public event ParcelAccessListReplyCallback OnAccessListReply;
private SecondLife Client;
/// <summary>
/// Default constructor
/// </summary>
/// <param name="client">A reference to the SecondLife client</param>
public ParcelManager(SecondLife client)
{
Client = client;
// Setup the callbacks
Client.Network.RegisterCallback(PacketType.ParcelInfoReply, new NetworkManager.PacketCallback(ParcelInfoReplyHandler));
Client.Network.RegisterCallback(PacketType.ParcelProperties, new NetworkManager.PacketCallback(ParcelPropertiesHandler));
Client.Network.RegisterCallback(PacketType.ParcelDwellReply, new NetworkManager.PacketCallback(ParcelDwellReplyHandler));
Client.Network.RegisterCallback(PacketType.ParcelAccessListReply, new NetworkManager.PacketCallback(ParcelAccessListReplyHandler));
}
/// <summary>
/// Request basic information for a single parcel
/// </summary>
/// <param name="parcelID">Simulator-local ID of the parcel</param>
public void InfoRequest(LLUUID parcelID)
{
ParcelInfoRequestPacket request = new ParcelInfoRequestPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.Data.ParcelID = parcelID;
Client.Network.SendPacket(request);
}
/// <summary>
/// Request properties of 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 ParcelProperties reply, useful for distinguishing between
/// different types of parcel property requests</param>
public void PropertiesRequest(Simulator simulator, int localID, int sequenceID)
{
ParcelPropertiesRequestByIDPacket request = new ParcelPropertiesRequestByIDPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.ParcelData.LocalID = localID;
request.ParcelData.SequenceID = sequenceID;
}
/// <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>
public void PropertiesRequest(Simulator simulator, float north, float east, float south, float west,
int sequenceID, bool snapSelection)
{
ParcelPropertiesRequestPacket request = new ParcelPropertiesRequestPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
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);
}
/// <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>
public void DwellRequest(Simulator simulator, int localID)
{
ParcelDwellRequestPacket request = new ParcelDwellRequestPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.Data.LocalID = localID;
request.Data.ParcelID = LLUUID.Zero; // Not used by clients
Client.Network.SendPacket(request, simulator);
}
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
/// <param name="forGroup"></param>
/// <param name="groupID"></param>
/// <param name="removeContribution"></param>
/// <returns></returns>
public void Buy(Simulator simulator, int localID, bool forGroup, LLUUID groupID, bool removeContribution)
{
ParcelBuyPacket request = new ParcelBuyPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.Data.Final = true;
request.Data.GroupID = groupID;
request.Data.LocalID = localID;
request.Data.IsGroupOwned = forGroup;
request.Data.RemoveContribution = removeContribution;
Client.Network.SendPacket(request, simulator);
}
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
public void Reclaim(Simulator simulator, int localID)
{
ParcelReclaimPacket request = new ParcelReclaimPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.Data.LocalID = localID;
Client.Network.SendPacket(request, simulator);
}
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
/// <param name="groupID"></param>
public void DeedToGroup(Simulator simulator, int localID, LLUUID groupID)
{
ParcelDeedToGroupPacket request = new ParcelDeedToGroupPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
request.Data.LocalID = localID;
request.Data.GroupID = groupID;
Client.Network.SendPacket(request, simulator);
}
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="localID"></param>
/// <param name="type"></param>
/// <param name="ownerIDs"></param>
public void ReturnObjects(Simulator simulator, int localID, ObjectReturnType type, List<LLUUID> ownerIDs)
{
ParcelReturnObjectsPacket request = new ParcelReturnObjectsPacket();
request.AgentData.AgentID = Client.Network.AgentID;
request.AgentData.SessionID = Client.Network.SessionID;
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();
request.TaskIDs[0].TaskID = LLUUID.Zero;
// 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);
}
private void ParcelDwellReplyHandler(Packet packet, Simulator simulator)
{
if (OnParcelDwell != null)
{
ParcelDwellReplyPacket dwell = (ParcelDwellReplyPacket)packet;
try { OnParcelDwell(dwell.Data.ParcelID, dwell.Data.LocalID, dwell.Data.Dwell); }
catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
private void ParcelInfoReplyHandler(Packet packet, Simulator simulator)
{
if (OnParcelInfo != null)
{
ParcelInfoReplyPacket info = (ParcelInfoReplyPacket)packet;
ParcelInfo parcelInfo = new ParcelInfo();
parcelInfo.ActualArea = info.Data.ActualArea;
parcelInfo.AuctionID = info.Data.AuctionID;
parcelInfo.BillableArea = info.Data.BillableArea;
parcelInfo.Description = Helpers.FieldToUTF8String(info.Data.Desc);
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;
parcelInfo.Name = Helpers.FieldToUTF8String(info.Data.Name);
parcelInfo.OwnerID = info.Data.OwnerID;
parcelInfo.SalePrice = info.Data.SalePrice;
parcelInfo.SimName = Helpers.FieldToUTF8String(info.Data.SimName);
parcelInfo.SnapshotID = info.Data.SnapshotID;
try { OnParcelInfo(parcelInfo); }
catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
private void ParcelPropertiesHandler(Packet packet, Simulator simulator)
{
if (OnParcelProperties != null)
{
ParcelPropertiesPacket properties = (ParcelPropertiesPacket)packet;
Parcel parcel = new Parcel(simulator, properties.ParcelData.LocalID);
parcel.AABBMax = properties.ParcelData.AABBMax;
parcel.AABBMin = properties.ParcelData.AABBMin;
parcel.Area = properties.ParcelData.Area;
parcel.AuctionID = properties.ParcelData.AuctionID;
parcel.AuthBuyerID = properties.ParcelData.AuthBuyerID;
parcel.Bitmap = properties.ParcelData.Bitmap;
parcel.Category = (Parcel.ParcelCategory)(sbyte)properties.ParcelData.Category;
parcel.ClaimDate = Helpers.UnixTimeToDateTime((uint)properties.ParcelData.ClaimDate);
// ClaimPrice seems to always be zero?
parcel.ClaimPrice = properties.ParcelData.ClaimPrice;
parcel.Desc = Helpers.FieldToUTF8String(properties.ParcelData.Desc);
parcel.GroupID = properties.ParcelData.GroupID;
parcel.GroupPrims = properties.ParcelData.GroupPrims;
parcel.IsGroupOwned = properties.ParcelData.IsGroupOwned;
parcel.LandingType = properties.ParcelData.LandingType;
parcel.MaxPrims = properties.ParcelData.MaxPrims;
parcel.MediaAutoScale = properties.ParcelData.MediaAutoScale;
parcel.MediaID = properties.ParcelData.MediaID;
parcel.MediaURL = Helpers.FieldToUTF8String(properties.ParcelData.MediaURL);
parcel.MusicURL = Helpers.FieldToUTF8String(properties.ParcelData.MusicURL);
parcel.Name = Helpers.FieldToUTF8String(properties.ParcelData.Name);
parcel.OtherCleanTime = properties.ParcelData.OtherCleanTime;
parcel.OtherCount = properties.ParcelData.OtherCount;
parcel.OtherPrims = properties.ParcelData.OtherPrims;
parcel.OwnerID = properties.ParcelData.OwnerID;
parcel.OwnerPrims = properties.ParcelData.OwnerPrims;
parcel.Flags = (Parcel.ParcelFlags)properties.ParcelData.ParcelFlags;
parcel.ParcelPrimBonus = properties.ParcelData.ParcelPrimBonus;
parcel.PassHours = properties.ParcelData.PassHours;
parcel.PassPrice = properties.ParcelData.PassPrice;
parcel.PublicCount = properties.ParcelData.PublicCount;
parcel.RegionDenyAnonymous = properties.ParcelData.RegionDenyAnonymous;
parcel.RegionDenyIdentified = properties.ParcelData.RegionDenyIdentified;
parcel.RegionDenyTransacted = properties.ParcelData.RegionDenyTransacted;
parcel.RegionPushOverride = properties.ParcelData.RegionPushOverride;
parcel.RentPrice = properties.ParcelData.RentPrice;
parcel.ReservedNewbie = properties.ParcelData.ReservedNewbie;
parcel.SalePrice = properties.ParcelData.SalePrice;
parcel.SelectedPrims = properties.ParcelData.SelectedPrims;
parcel.SelfCount = properties.ParcelData.SelfCount;
parcel.SimWideMaxPrims = properties.ParcelData.SimWideMaxPrims;
parcel.SimWideTotalPrims = properties.ParcelData.SimWideTotalPrims;
parcel.SnapshotID = properties.ParcelData.SnapshotID;
parcel.Status = (Parcel.ParcelStatus)(sbyte)properties.ParcelData.Status;
parcel.TotalPrims = properties.ParcelData.TotalPrims;
parcel.UserLocation = properties.ParcelData.UserLocation;
parcel.UserLookAt = properties.ParcelData.UserLookAt;
// Fire the callback
try
{
OnParcelProperties(parcel, (ParcelResult)properties.ParcelData.RequestResult,
properties.ParcelData.SequenceID, properties.ParcelData.SnapSelection);
}
catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
protected void ParcelAccessListReplyHandler(Packet packet, Simulator simulator)
{
if (OnAccessListReply != null)
{
ParcelAccessListReplyPacket reply = (ParcelAccessListReplyPacket)packet;
List<ParcelAccessEntry> accessList = new List<ParcelAccessEntry>();
foreach( ParcelAccessListReplyPacket.ListBlock block in reply.List )
{
ParcelAccessEntry pae = new ParcelAccessEntry();
pae.AgentID = block.ID;
pae.Flags = block.Flags;
pae.Time = block.Time;
accessList.Add(pae);
}
try
{
OnAccessListReply(reply.Data.SequenceID, reply.Data.LocalID, reply.Data.Flags, accessList);
} catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
}
}