1639 lines
74 KiB
C#
1639 lines
74 KiB
C#
/*
|
|
* Copyright (c) 2006-2016, openmetaverse.co
|
|
* 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 openmetaverse.co 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.Threading;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenMetaverse.Packets;
|
|
using OpenMetaverse.Interfaces;
|
|
using OpenMetaverse.Messages.Linden;
|
|
|
|
namespace OpenMetaverse
|
|
{
|
|
/// <summary>
|
|
/// Access to the data server which allows searching for land, events, people, etc
|
|
/// </summary>
|
|
public class DirectoryManager
|
|
{
|
|
#region Enums
|
|
/// <summary>Classified Ad categories</summary>
|
|
public enum ClassifiedCategories
|
|
{
|
|
/// <summary>Classified is listed in the Any category</summary>
|
|
Any = 0,
|
|
/// <summary>Classified is shopping related</summary>
|
|
Shopping,
|
|
/// <summary>Classified is </summary>
|
|
LandRental,
|
|
/// <summary></summary>
|
|
PropertyRental,
|
|
/// <summary></summary>
|
|
SpecialAttraction,
|
|
/// <summary></summary>
|
|
NewProducts,
|
|
/// <summary></summary>
|
|
Employment,
|
|
/// <summary></summary>
|
|
Wanted,
|
|
/// <summary></summary>
|
|
Service,
|
|
/// <summary></summary>
|
|
Personal
|
|
}
|
|
|
|
/// <summary>Event Categories</summary>
|
|
public enum EventCategories
|
|
{
|
|
/// <summary></summary>
|
|
All = 0,
|
|
/// <summary></summary>
|
|
Discussion = 18,
|
|
/// <summary></summary>
|
|
Sports = 19,
|
|
/// <summary></summary>
|
|
LiveMusic = 20,
|
|
/// <summary></summary>
|
|
Commercial = 22,
|
|
/// <summary></summary>
|
|
Nightlife = 23,
|
|
/// <summary></summary>
|
|
Games = 24,
|
|
/// <summary></summary>
|
|
Pageants = 25,
|
|
/// <summary></summary>
|
|
Education = 26,
|
|
/// <summary></summary>
|
|
Arts = 27,
|
|
/// <summary></summary>
|
|
Charity = 28,
|
|
/// <summary></summary>
|
|
Miscellaneous = 29
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Flags used in many of the DirectoryManager methods to specify which query to execute and how to return the results.
|
|
///
|
|
/// Flags can be combined using the | (pipe) character, not all flags are available in all queries
|
|
/// </summary>
|
|
[Flags]
|
|
public enum DirFindFlags
|
|
{
|
|
/// <summary>Query the People database</summary>
|
|
People = 1 << 0,
|
|
/// <summary></summary>
|
|
Online = 1 << 1,
|
|
// <summary></summary>
|
|
//[Obsolete]
|
|
//Places = 1 << 2,
|
|
/// <summary></summary>
|
|
Events = 1 << 3,
|
|
/// <summary>Query the Groups database</summary>
|
|
Groups = 1 << 4,
|
|
/// <summary>Query the Events database</summary>
|
|
DateEvents = 1 << 5,
|
|
/// <summary>Query the land holdings database for land owned by the currently connected agent</summary>
|
|
AgentOwned = 1 << 6,
|
|
/// <summary></summary>
|
|
ForSale = 1 << 7,
|
|
/// <summary>Query the land holdings database for land which is owned by a Group</summary>
|
|
GroupOwned = 1 << 8,
|
|
// <summary></summary>
|
|
//[Obsolete]
|
|
//Auction = 1 << 9,
|
|
/// <summary>Specifies the query should pre sort the results based upon traffic
|
|
/// when searching the Places database</summary>
|
|
DwellSort = 1 << 10,
|
|
/// <summary></summary>
|
|
PgSimsOnly = 1 << 11,
|
|
/// <summary></summary>
|
|
PicturesOnly = 1 << 12,
|
|
/// <summary></summary>
|
|
PgEventsOnly = 1 << 13,
|
|
/// <summary></summary>
|
|
MatureSimsOnly = 1 << 14,
|
|
/// <summary>Specifies the query should pre sort the results in an ascending order when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
SortAsc = 1 << 15,
|
|
/// <summary>Specifies the query should pre sort the results using the SalePrice field when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
PricesSort = 1 << 16,
|
|
/// <summary>Specifies the query should pre sort the results by calculating the average price/sq.m (SalePrice / Area) when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
PerMeterSort = 1 << 17,
|
|
/// <summary>Specifies the query should pre sort the results using the ParcelSize field when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
AreaSort = 1 << 18,
|
|
/// <summary>Specifies the query should pre sort the results using the Name field when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
NameSort = 1 << 19,
|
|
/// <summary>When set, only parcels less than the specified Price will be included when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
LimitByPrice = 1 << 20,
|
|
/// <summary>When set, only parcels greater than the specified Size will be included when searching the land sales database.
|
|
/// This flag is only used when searching the land sales database</summary>
|
|
LimitByArea = 1 << 21,
|
|
/// <summary></summary>
|
|
FilterMature = 1 << 22,
|
|
/// <summary></summary>
|
|
PGOnly = 1 << 23,
|
|
/// <summary>Include PG land in results. This flag is used when searching both the Groups, Events and Land sales databases</summary>
|
|
IncludePG = 1 << 24,
|
|
/// <summary>Include Mature land in results. This flag is used when searching both the Groups, Events and Land sales databases</summary>
|
|
IncludeMature = 1 << 25,
|
|
/// <summary>Include Adult land in results. This flag is used when searching both the Groups, Events and Land sales databases</summary>
|
|
IncludeAdult = 1 << 26,
|
|
/// <summary></summary>
|
|
AdultOnly = 1 << 27
|
|
}
|
|
|
|
/// <summary>
|
|
/// Land types to search dataserver for
|
|
/// </summary>
|
|
[Flags]
|
|
public enum SearchTypeFlags
|
|
{
|
|
/// <summary>Search Auction, Mainland and Estate</summary>
|
|
Any = -1,
|
|
/// <summary>Land which is currently up for auction</summary>
|
|
Auction = 1 << 1,
|
|
// <summary>Land available to new landowners (formerly the FirstLand program)</summary>
|
|
//[Obsolete]
|
|
//Newbie = 1 << 2,
|
|
/// <summary>Parcels which are on the mainland (Linden owned) continents</summary>
|
|
Mainland = 1 << 3,
|
|
/// <summary>Parcels which are on privately owned simulators</summary>
|
|
Estate = 1 << 4
|
|
}
|
|
|
|
/// <summary>
|
|
/// The content rating of the event
|
|
/// </summary>
|
|
public enum EventFlags
|
|
{
|
|
/// <summary>Event is PG</summary>
|
|
PG = 0,
|
|
/// <summary>Event is Mature</summary>
|
|
Mature = 1,
|
|
/// <summary>Event is Adult</summary>
|
|
Adult = 2
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classified Ad Options
|
|
/// </summary>
|
|
/// <remarks>There appear to be two formats the flags are packed in.
|
|
/// This set of flags is for the newer style</remarks>
|
|
[Flags]
|
|
public enum ClassifiedFlags : byte
|
|
{
|
|
/// <summary></summary>
|
|
None = 1 << 0,
|
|
/// <summary></summary>
|
|
Mature = 1 << 1,
|
|
/// <summary></summary>
|
|
Enabled = 1 << 2,
|
|
// HasPrice = 1 << 3, // Deprecated
|
|
/// <summary></summary>
|
|
UpdateTime = 1 << 4,
|
|
/// <summary></summary>
|
|
AutoRenew = 1 << 5
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classified ad query options
|
|
/// </summary>
|
|
[Flags]
|
|
public enum ClassifiedQueryFlags
|
|
{
|
|
/// <summary>Include all ads in results</summary>
|
|
All = PG | Mature | Adult,
|
|
/// <summary>Include PG ads in results</summary>
|
|
PG = 1 << 2,
|
|
/// <summary>Include Mature ads in results</summary>
|
|
Mature = 1 << 3,
|
|
/// <summary>Include Adult ads in results</summary>
|
|
Adult = 1 << 6,
|
|
}
|
|
|
|
/// <summary>
|
|
/// The For Sale flag in PlacesReplyData
|
|
/// </summary>
|
|
public enum PlacesFlags : byte
|
|
{
|
|
/// <summary>Parcel is not listed for sale</summary>
|
|
NotForSale = 0,
|
|
/// <summary>Parcel is For Sale</summary>
|
|
ForSale = 128
|
|
}
|
|
|
|
#endregion
|
|
#region Structs
|
|
/// <summary>
|
|
/// A classified ad on the grid
|
|
/// </summary>
|
|
public struct Classified
|
|
{
|
|
/// <summary>UUID for this ad, useful for looking up detailed
|
|
/// information about it</summary>
|
|
public UUID ID;
|
|
/// <summary>The title of this classified ad</summary>
|
|
public string Name;
|
|
/// <summary>Flags that show certain options applied to the classified</summary>
|
|
public ClassifiedFlags Flags;
|
|
/// <summary>Creation date of the ad</summary>
|
|
public DateTime CreationDate;
|
|
/// <summary>Expiration date of the ad</summary>
|
|
public DateTime ExpirationDate;
|
|
/// <summary>Price that was paid for this ad</summary>
|
|
public int Price;
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A parcel retrieved from the dataserver such as results from the
|
|
/// "For-Sale" listings or "Places" Search
|
|
/// </summary>
|
|
public struct DirectoryParcel
|
|
{
|
|
/// <summary>The unique dataserver parcel ID</summary>
|
|
/// <remarks>This id is used to obtain additional information from the entry
|
|
/// by using the <see cref="ParcelManager.InfoRequest"/> method</remarks>
|
|
public UUID ID;
|
|
/// <summary>A string containing the name of the parcel</summary>
|
|
public string Name;
|
|
/// <summary>The size of the parcel</summary>
|
|
/// <remarks>This field is not returned for Places searches</remarks>
|
|
public int ActualArea;
|
|
/// <summary>The price of the parcel</summary>
|
|
/// <remarks>This field is not returned for Places searches</remarks>
|
|
public int SalePrice;
|
|
/// <summary>If True, this parcel is flagged to be auctioned</summary>
|
|
public bool Auction;
|
|
/// <summary>If true, this parcel is currently set for sale</summary>
|
|
public bool ForSale;
|
|
/// <summary>Parcel traffic</summary>
|
|
public float Dwell;
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An Avatar returned from the dataserver
|
|
/// </summary>
|
|
public struct AgentSearchData
|
|
{
|
|
/// <summary>Online status of agent</summary>
|
|
/// <remarks>This field appears to be obsolete and always returns false</remarks>
|
|
public bool Online;
|
|
/// <summary>The agents first name</summary>
|
|
public string FirstName;
|
|
/// <summary>The agents last name</summary>
|
|
public string LastName;
|
|
/// <summary>The agents <see cref="UUID"/></summary>
|
|
public UUID AgentID;
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Response to a "Groups" Search
|
|
/// </summary>
|
|
public struct GroupSearchData
|
|
{
|
|
/// <summary>The Group ID</summary>
|
|
public UUID GroupID;
|
|
/// <summary>The name of the group</summary>
|
|
public string GroupName;
|
|
/// <summary>The current number of members</summary>
|
|
public int Members;
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parcel information returned from a <see cref="DirectoryManager.StartPlacesSearch"/> request
|
|
/// <para>
|
|
/// Represents one of the following:
|
|
/// A parcel of land on the grid that has its Show In Search flag set
|
|
/// A parcel of land owned by the agent making the request
|
|
/// A parcel of land owned by a group the agent making the request is a member of
|
|
/// </para>
|
|
/// <para>
|
|
/// In a request for Group Land, the First record will contain an empty record
|
|
/// </para>
|
|
/// Note: This is not the same as searching the land for sale data source
|
|
/// </summary>
|
|
public struct PlacesSearchData
|
|
{
|
|
/// <summary>The ID of the Agent of Group that owns the parcel</summary>
|
|
public UUID OwnerID;
|
|
/// <summary>The name</summary>
|
|
public string Name;
|
|
/// <summary>The description</summary>
|
|
public string Desc;
|
|
/// <summary>The Size of the parcel</summary>
|
|
public int ActualArea;
|
|
/// <summary>The billable Size of the parcel, for mainland
|
|
/// parcels this will match the ActualArea field. For Group owned land this will be 10 percent smaller
|
|
/// than the ActualArea. For Estate land this will always be 0</summary>
|
|
public int BillableArea;
|
|
/// <summary>Indicates the ForSale status of the parcel</summary>
|
|
public PlacesFlags Flags;
|
|
/// <summary>The Gridwide X position</summary>
|
|
public float GlobalX;
|
|
/// <summary>The Gridwide Y position</summary>
|
|
public float GlobalY;
|
|
/// <summary>The Z position of the parcel, or 0 if no landing point set</summary>
|
|
public float GlobalZ;
|
|
/// <summary>The name of the Region the parcel is located in</summary>
|
|
public string SimName;
|
|
/// <summary>The Asset ID of the parcels Snapshot texture</summary>
|
|
public UUID SnapshotID;
|
|
/// <summary>The calculated visitor traffic</summary>
|
|
public float Dwell;
|
|
/// <summary>The billing product SKU</summary>
|
|
/// <remarks>Known values are:
|
|
/// <list type="table">
|
|
/// <item><term>023</term><description>Mainland / Full Region</description></item>
|
|
/// <item><term>024</term><description>Estate / Full Region</description></item>
|
|
/// <item><term>027</term><description>Estate / Openspace</description></item>
|
|
/// <item><term>029</term><description>Estate / Homestead</description></item>
|
|
/// <item><term>129</term><description>Mainland / Homestead (Linden Owned)</description></item>
|
|
/// </list>
|
|
/// </remarks>
|
|
public string SKU;
|
|
/// <summary>No longer used, will always be 0</summary>
|
|
public int Price;
|
|
|
|
/// <summary>Get a SL URL for the parcel</summary>
|
|
/// <returns>A string, containing a standard SLURL</returns>
|
|
public string ToSLurl()
|
|
{
|
|
float x, y;
|
|
Helpers.GlobalPosToRegionHandle(this.GlobalX, this.GlobalY, out x, out y);
|
|
return "secondlife://" + this.SimName + "/" + x + "/" + y + "/" + this.GlobalZ;
|
|
}
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An "Event" Listing summary
|
|
/// </summary>
|
|
public struct EventsSearchData
|
|
{
|
|
/// <summary>The ID of the event creator</summary>
|
|
public UUID Owner;
|
|
/// <summary>The name of the event</summary>
|
|
public string Name;
|
|
/// <summary>The events ID</summary>
|
|
public uint ID;
|
|
/// <summary>A string containing the short date/time the event will begin</summary>
|
|
public string Date;
|
|
/// <summary>The event start time in Unixtime (seconds since epoch)</summary>
|
|
public uint Time;
|
|
/// <summary>The events maturity rating</summary>
|
|
public EventFlags Flags;
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The details of an "Event"
|
|
/// </summary>
|
|
public struct EventInfo
|
|
{
|
|
/// <summary>The events ID</summary>
|
|
public uint ID;
|
|
/// <summary>The ID of the event creator</summary>
|
|
public UUID Creator;
|
|
/// <summary>The name of the event</summary>
|
|
public string Name;
|
|
/// <summary>The category</summary>
|
|
public EventCategories Category;
|
|
/// <summary>The events description</summary>
|
|
public string Desc;
|
|
/// <summary>The short date/time the event will begin</summary>
|
|
public string Date;
|
|
/// <summary>The event start time in Unixtime (seconds since epoch) UTC adjusted</summary>
|
|
public uint DateUTC;
|
|
/// <summary>The length of the event in minutes</summary>
|
|
public uint Duration;
|
|
/// <summary>0 if no cover charge applies</summary>
|
|
public uint Cover;
|
|
/// <summary>The cover charge amount in L$ if applicable</summary>
|
|
public uint Amount;
|
|
/// <summary>The name of the region where the event is being held</summary>
|
|
public string SimName;
|
|
/// <summary>The gridwide location of the event</summary>
|
|
public Vector3d GlobalPos;
|
|
/// <summary>The maturity rating</summary>
|
|
public EventFlags Flags;
|
|
|
|
/// <summary>Get a SL URL for the parcel where the event is hosted</summary>
|
|
/// <returns>A string, containing a standard SLURL</returns>
|
|
public string ToSLurl()
|
|
{
|
|
float x, y;
|
|
Helpers.GlobalPosToRegionHandle((float)this.GlobalPos.X, (float)this.GlobalPos.Y, out x, out y);
|
|
return "secondlife://" + this.SimName + "/" + x + "/" + y + "/" + this.GlobalPos.Z;
|
|
}
|
|
|
|
/// <summary>Print the struct data as a string</summary>
|
|
/// <returns>A string containing the field name, and field value</returns>
|
|
public override string ToString()
|
|
{
|
|
return Helpers.StructToString(this);
|
|
}
|
|
}
|
|
|
|
#endregion Structs
|
|
|
|
#region Event delegates, Raise Events
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<EventInfoReplyEventArgs> m_EventInfoReply;
|
|
|
|
/// <summary>Raises the EventInfoReply event</summary>
|
|
/// <param name="e">An EventInfoReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnEventInfo(EventInfoReplyEventArgs e)
|
|
{
|
|
EventHandler<EventInfoReplyEventArgs> handler = m_EventInfoReply;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_EventDetailLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="EventInfoRequest"/> request.</summary>
|
|
public event EventHandler<EventInfoReplyEventArgs> EventInfoReply
|
|
{
|
|
add { lock (m_EventDetailLock) { m_EventInfoReply += value; } }
|
|
remove { lock (m_EventDetailLock) { m_EventInfoReply -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirEventsReplyEventArgs> m_DirEvents;
|
|
|
|
/// <summary>Raises the DirEventsReply event</summary>
|
|
/// <param name="e">An DirEventsReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirEvents(DirEventsReplyEventArgs e)
|
|
{
|
|
EventHandler<DirEventsReplyEventArgs> handler = m_DirEvents;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirEventsLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartEventsSearch"/> request.</summary>
|
|
public event EventHandler<DirEventsReplyEventArgs> DirEventsReply
|
|
{
|
|
add { lock (m_DirEventsLock) { m_DirEvents += value; } }
|
|
remove { lock (m_DirEventsLock) { m_DirEvents -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<PlacesReplyEventArgs> m_Places;
|
|
|
|
/// <summary>Raises the PlacesReply event</summary>
|
|
/// <param name="e">A PlacesReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnPlaces(PlacesReplyEventArgs e)
|
|
{
|
|
EventHandler<PlacesReplyEventArgs> handler = m_Places;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_PlacesLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartPlacesSearch"/> request.</summary>
|
|
public event EventHandler<PlacesReplyEventArgs> PlacesReply
|
|
{
|
|
add { lock (m_PlacesLock) { m_Places += value; } }
|
|
remove { lock (m_PlacesLock) { m_Places -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirPlacesReplyEventArgs> m_DirPlaces;
|
|
|
|
/// <summary>Raises the DirPlacesReply event</summary>
|
|
/// <param name="e">A DirPlacesReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirPlaces(DirPlacesReplyEventArgs e)
|
|
{
|
|
EventHandler<DirPlacesReplyEventArgs> handler = m_DirPlaces;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirPlacesLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartDirPlacesSearch"/> request.</summary>
|
|
public event EventHandler<DirPlacesReplyEventArgs> DirPlacesReply
|
|
{
|
|
add { lock (m_DirPlacesLock) { m_DirPlaces += value; } }
|
|
remove { lock (m_DirPlacesLock) { m_DirPlaces -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirClassifiedsReplyEventArgs> m_DirClassifieds;
|
|
|
|
/// <summary>Raises the DirClassifiedsReply event</summary>
|
|
/// <param name="e">A DirClassifiedsReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirClassifieds(DirClassifiedsReplyEventArgs e)
|
|
{
|
|
EventHandler<DirClassifiedsReplyEventArgs> handler = m_DirClassifieds;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirClassifiedsLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartClassifiedSearch"/> request.</summary>
|
|
public event EventHandler<DirClassifiedsReplyEventArgs> DirClassifiedsReply
|
|
{
|
|
add { lock (m_DirClassifiedsLock) { m_DirClassifieds += value; } }
|
|
remove { lock (m_DirClassifiedsLock) { m_DirClassifieds -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirGroupsReplyEventArgs> m_DirGroups;
|
|
|
|
/// <summary>Raises the DirGroupsReply event</summary>
|
|
/// <param name="e">A DirGroupsReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirGroups(DirGroupsReplyEventArgs e)
|
|
{
|
|
EventHandler<DirGroupsReplyEventArgs> handler = m_DirGroups;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirGroupsLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartGroupSearch"/> request.</summary>
|
|
public event EventHandler<DirGroupsReplyEventArgs> DirGroupsReply
|
|
{
|
|
add { lock (m_DirGroupsLock) { m_DirGroups += value; } }
|
|
remove { lock (m_DirGroupsLock) { m_DirGroups -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirPeopleReplyEventArgs> m_DirPeople;
|
|
|
|
/// <summary>Raises the DirPeopleReply event</summary>
|
|
/// <param name="e">A DirPeopleReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirPeople(DirPeopleReplyEventArgs e)
|
|
{
|
|
EventHandler<DirPeopleReplyEventArgs> handler = m_DirPeople;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirPeopleLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartPeopleSearch"/> request.</summary>
|
|
public event EventHandler<DirPeopleReplyEventArgs> DirPeopleReply
|
|
{
|
|
add { lock (m_DirPeopleLock) { m_DirPeople += value; } }
|
|
remove { lock (m_DirPeopleLock) { m_DirPeople -= value; } }
|
|
}
|
|
|
|
/// <summary>The event subscribers. null if no subscribers</summary>
|
|
private EventHandler<DirLandReplyEventArgs> m_DirLandReply;
|
|
|
|
/// <summary>Raises the DirLandReply event</summary>
|
|
/// <param name="e">A DirLandReplyEventArgs object containing the
|
|
/// data returned from the data server</param>
|
|
protected virtual void OnDirLand(DirLandReplyEventArgs e)
|
|
{
|
|
EventHandler<DirLandReplyEventArgs> handler = m_DirLandReply;
|
|
handler?.Invoke(this, e);
|
|
}
|
|
|
|
/// <summary>Thread sync lock object</summary>
|
|
private readonly object m_DirLandLock = new object();
|
|
|
|
/// <summary>Raised when the data server responds to a <see cref="DirectoryManager.StartLandSearch"/> request.</summary>
|
|
public event EventHandler<DirLandReplyEventArgs> DirLandReply
|
|
{
|
|
add { lock (m_DirLandLock) { m_DirLandReply += value; } }
|
|
remove { lock (m_DirLandLock) { m_DirLandReply -= value; } }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Members
|
|
private GridClient Client;
|
|
#endregion
|
|
|
|
#region Constructors
|
|
/// <summary>
|
|
/// Constructs a new instance of the DirectoryManager class
|
|
/// </summary>
|
|
/// <param name="client">An instance of GridClient</param>
|
|
public DirectoryManager(GridClient client)
|
|
{
|
|
Client = client;
|
|
|
|
Client.Network.RegisterCallback(PacketType.DirClassifiedReply, DirClassifiedReplyHandler);
|
|
// Deprecated, replies come in over capabilities
|
|
Client.Network.RegisterCallback(PacketType.DirLandReply, DirLandReplyHandler);
|
|
Client.Network.RegisterEventCallback("DirLandReply", DirLandReplyEventHandler);
|
|
Client.Network.RegisterCallback(PacketType.DirPeopleReply, DirPeopleReplyHandler);
|
|
Client.Network.RegisterCallback(PacketType.DirGroupsReply, DirGroupsReplyHandler);
|
|
// Deprecated as of viewer 1.2.3
|
|
Client.Network.RegisterCallback(PacketType.PlacesReply, PlacesReplyHandler);
|
|
Client.Network.RegisterEventCallback("PlacesReply", PlacesReplyEventHandler);
|
|
Client.Network.RegisterCallback(PacketType.DirEventsReply, EventsReplyHandler);
|
|
Client.Network.RegisterCallback(PacketType.EventInfoReply, EventInfoReplyHandler);
|
|
Client.Network.RegisterCallback(PacketType.DirPlacesReply, DirPlacesReplyHandler);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
// Obsoleted due to new Adult search option
|
|
[Obsolete("Use Overload with ClassifiedQueryFlags option instead")]
|
|
public UUID StartClassifiedSearch(string searchText, ClassifiedCategories category, bool mature)
|
|
{
|
|
return UUID.Zero;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query the data server for a list of classified ads containing the specified string.
|
|
/// Defaults to searching for classified placed in any category, and includes PG, Adult and Mature
|
|
/// results.
|
|
///
|
|
/// Responses are sent 16 per response packet, there is no way to know how many results a query reply will contain however assuming
|
|
/// the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received
|
|
///
|
|
/// The <see cref="OnClassifiedReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing a list of keywords to search for</param>
|
|
/// <returns>A UUID to correlate the results when the <see cref="OnClassifiedReply"/> event is raised</returns>
|
|
public UUID StartClassifiedSearch(string searchText)
|
|
{
|
|
return StartClassifiedSearch(searchText, ClassifiedCategories.Any, ClassifiedQueryFlags.All);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query the data server for a list of classified ads which contain specified keywords (Overload)
|
|
///
|
|
/// The <see cref="OnClassifiedReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing a list of keywords to search for</param>
|
|
/// <param name="category">The category to search</param>
|
|
/// <param name="queryFlags">A set of flags which can be ORed to modify query options
|
|
/// such as classified maturity rating.</param>
|
|
/// <returns>A UUID to correlate the results when the <see cref="OnClassifiedReply"/> event is raised</returns>
|
|
/// <example>
|
|
/// Search classified ads containing the key words "foo" and "bar" in the "Any" category that are either PG or Mature
|
|
/// <code>
|
|
/// UUID searchID = StartClassifiedSearch("foo bar", ClassifiedCategories.Any, ClassifiedQueryFlags.PG | ClassifiedQueryFlags.Mature);
|
|
/// </code>
|
|
/// </example>
|
|
/// <remarks>
|
|
/// Responses are sent 16 at a time, there is no way to know how many results a query reply will contain however assuming
|
|
/// the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received
|
|
/// </remarks>
|
|
public UUID StartClassifiedSearch(string searchText, ClassifiedCategories category, ClassifiedQueryFlags queryFlags)
|
|
{
|
|
DirClassifiedQueryPacket query = new DirClassifiedQueryPacket();
|
|
UUID queryID = UUID.Random();
|
|
|
|
query.AgentData.AgentID = Client.Self.AgentID;
|
|
query.AgentData.SessionID = Client.Self.SessionID;
|
|
|
|
query.QueryData.Category = (uint)category;
|
|
query.QueryData.QueryFlags = (uint)queryFlags;
|
|
query.QueryData.QueryID = queryID;
|
|
query.QueryData.QueryText = Utils.StringToBytes(searchText);
|
|
|
|
Client.Network.SendPacket(query);
|
|
|
|
return queryID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts search for places (Overloaded)
|
|
///
|
|
/// The <see cref="OnDirPlacesReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="searchText">Search text</param>
|
|
/// <param name="queryStart">Each request is limited to 100 places
|
|
/// being returned. To get the first 100 result entries of a request use 0,
|
|
/// from 100-199 use 1, 200-299 use 2, etc.</param>
|
|
/// <returns>A UUID to correlate the results when the <see cref="OnDirPlacesReply"/> event is raised</returns>
|
|
public UUID StartDirPlacesSearch(string searchText, int queryStart)
|
|
{
|
|
return StartDirPlacesSearch(searchText, DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeMature
|
|
| DirFindFlags.IncludeAdult, ParcelCategory.Any, queryStart);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Queries the dataserver for parcels of land which are flagged to be shown in search
|
|
///
|
|
/// The <see cref="OnDirPlacesReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
|
/// <param name="queryFlags">A set of flags which can be ORed to modify query options
|
|
/// such as classified maturity rating.</param>
|
|
/// <param name="category">The category to search</param>
|
|
/// <param name="queryStart">Each request is limited to 100 places
|
|
/// being returned. To get the first 100 result entries of a request use 0,
|
|
/// from 100-199 use 1, 200-299 use 2, etc.</param>
|
|
/// <returns>A UUID to correlate the results when the <see cref="OnDirPlacesReply"/> event is raised</returns>
|
|
/// <example>
|
|
/// Search places containing the key words "foo" and "bar" in the "Any" category that are either PG or Adult
|
|
/// <code>
|
|
/// UUID searchID = StartDirPlacesSearch("foo bar", DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeAdult, ParcelCategory.Any, 0);
|
|
/// </code>
|
|
/// </example>
|
|
/// <remarks>
|
|
/// Additional information on the results can be obtained by using the ParcelManager.InfoRequest method
|
|
/// </remarks>
|
|
public UUID StartDirPlacesSearch(string searchText, DirFindFlags queryFlags, ParcelCategory category, int queryStart)
|
|
{
|
|
DirPlacesQueryPacket query = new DirPlacesQueryPacket();
|
|
|
|
UUID queryID = UUID.Random();
|
|
|
|
query.AgentData.AgentID = Client.Self.AgentID;
|
|
query.AgentData.SessionID = Client.Self.SessionID;
|
|
|
|
query.QueryData.Category = (sbyte)category;
|
|
query.QueryData.QueryFlags = (uint)queryFlags;
|
|
|
|
query.QueryData.QueryID = queryID;
|
|
query.QueryData.QueryText = Utils.StringToBytes(searchText);
|
|
query.QueryData.QueryStart = queryStart;
|
|
query.QueryData.SimName = Utils.StringToBytes(string.Empty);
|
|
|
|
Client.Network.SendPacket(query);
|
|
|
|
return queryID;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts a search for land sales using the directory
|
|
///
|
|
/// The <see cref="OnDirLandReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="typeFlags">What type of land to search for. Auction,
|
|
/// estate, mainland, "first land", etc</param>
|
|
/// <remarks>The OnDirLandReply event handler must be registered before
|
|
/// calling this function. There is no way to determine how many
|
|
/// results will be returned, or how many times the callback will be
|
|
/// fired other than you won't get more than 100 total parcels from
|
|
/// each query.</remarks>
|
|
public void StartLandSearch(SearchTypeFlags typeFlags)
|
|
{
|
|
StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort, typeFlags, 0, 0, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts a search for land sales using the directory
|
|
///
|
|
/// The <see cref="OnDirLandReply"/> event is raised when a response is received from the simulator
|
|
/// </summary>
|
|
/// <param name="typeFlags">What type of land to search for. Auction,
|
|
/// estate, mainland, "first land", etc</param>
|
|
/// <param name="priceLimit">Maximum price to search for</param>
|
|
/// <param name="areaLimit">Maximum area to search for</param>
|
|
/// <param name="queryStart">Each request is limited to 100 parcels
|
|
/// being returned. To get the first 100 parcels of a request use 0,
|
|
/// from 100-199 use 1, 200-299 use 2, etc.</param>
|
|
/// <remarks>The OnDirLandReply event handler must be registered before
|
|
/// calling this function. There is no way to determine how many
|
|
/// results will be returned, or how many times the callback will be
|
|
/// fired other than you won't get more than 100 total parcels from
|
|
/// each query.</remarks>
|
|
public void StartLandSearch(SearchTypeFlags typeFlags, int priceLimit, int areaLimit, int queryStart)
|
|
{
|
|
StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByPrice |
|
|
DirFindFlags.LimitByArea, typeFlags, priceLimit, areaLimit, queryStart);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send a request to the data server for land sales listings
|
|
/// </summary>
|
|
///
|
|
/// <param name="findFlags">Flags sent to specify query options
|
|
///
|
|
/// Available flags:
|
|
/// Specify the parcel rating with one or more of the following:
|
|
/// IncludePG IncludeMature IncludeAdult
|
|
///
|
|
/// Specify the field to pre sort the results with ONLY ONE of the following:
|
|
/// PerMeterSort NameSort AreaSort PricesSort
|
|
///
|
|
/// Specify the order the results are returned in, if not specified the results are pre sorted in a Descending Order
|
|
/// SortAsc
|
|
///
|
|
/// Specify additional filters to limit the results with one or both of the following:
|
|
/// LimitByPrice LimitByArea
|
|
///
|
|
/// Flags can be combined by separating them with the | (pipe) character
|
|
///
|
|
/// Additional details can be found in <see cref="DirFindFlags"/>
|
|
/// </param>
|
|
/// <param name="typeFlags">What type of land to search for. Auction,
|
|
/// Estate or Mainland</param>
|
|
/// <param name="priceLimit">Maximum price to search for when the
|
|
/// DirFindFlags.LimitByPrice flag is specified in findFlags</param>
|
|
/// <param name="areaLimit">Maximum area to search for when the
|
|
/// DirFindFlags.LimitByArea flag is specified in findFlags</param>
|
|
/// <param name="queryStart">Each request is limited to 100 parcels
|
|
/// being returned. To get the first 100 parcels of a request use 0,
|
|
/// from 100-199 use 100, 200-299 use 200, etc.</param>
|
|
/// <remarks><para>The <see cref="OnDirLandReply"/> event will be raised with the response from the simulator
|
|
///
|
|
/// There is no way to determine how many results will be returned, or how many times the callback will be
|
|
/// fired other than you won't get more than 100 total parcels from
|
|
/// each reply.</para>
|
|
///
|
|
/// <para>Any land set for sale to either anybody or specific to the connected agent will be included in the
|
|
/// results if the land is included in the query</para></remarks>
|
|
/// <example>
|
|
/// <code>
|
|
/// // request all mainland, any maturity rating that is larger than 512 sq.m
|
|
/// StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByArea | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult, SearchTypeFlags.Mainland, 0, 512, 0);
|
|
/// </code></example>
|
|
public void StartLandSearch(DirFindFlags findFlags, SearchTypeFlags typeFlags, int priceLimit,
|
|
int areaLimit, int queryStart)
|
|
{
|
|
DirLandQueryPacket query = new DirLandQueryPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID
|
|
},
|
|
QueryData =
|
|
{
|
|
Area = areaLimit,
|
|
Price = priceLimit,
|
|
QueryStart = queryStart,
|
|
SearchType = (uint)typeFlags,
|
|
QueryFlags = (uint)findFlags,
|
|
QueryID = UUID.Random()
|
|
}
|
|
};
|
|
|
|
Client.Network.SendPacket(query);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search for Groups
|
|
/// </summary>
|
|
/// <param name="searchText">The name or portion of the name of the group you wish to search for</param>
|
|
/// <param name="queryStart">Start from the match number</param>
|
|
/// <returns></returns>
|
|
public UUID StartGroupSearch(string searchText, int queryStart)
|
|
{
|
|
return StartGroupSearch(searchText, queryStart, DirFindFlags.Groups | DirFindFlags.IncludePG
|
|
| DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search for Groups
|
|
/// </summary>
|
|
/// <param name="searchText">The name or portion of the name of the group you wish to search for</param>
|
|
/// <param name="queryStart">Start from the match number</param>
|
|
/// <param name="flags">Search flags</param>
|
|
/// <returns></returns>
|
|
public UUID StartGroupSearch(string searchText, int queryStart, DirFindFlags flags)
|
|
{
|
|
DirFindQueryPacket find = new DirFindQueryPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID
|
|
},
|
|
QueryData =
|
|
{
|
|
QueryFlags = (uint)flags,
|
|
QueryText = Utils.StringToBytes(searchText),
|
|
QueryID = UUID.Random(),
|
|
QueryStart = queryStart
|
|
}
|
|
};
|
|
|
|
Client.Network.SendPacket(find);
|
|
|
|
return find.QueryData.QueryID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search the People directory for other avatars
|
|
/// </summary>
|
|
/// <param name="searchText">The name or portion of the name of the avatar you wish to search for</param>
|
|
/// <param name="queryStart"></param>
|
|
/// <returns></returns>
|
|
public UUID StartPeopleSearch(string searchText, int queryStart)
|
|
{
|
|
DirFindQueryPacket find = new DirFindQueryPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID
|
|
},
|
|
QueryData =
|
|
{
|
|
QueryFlags = (uint)DirFindFlags.People,
|
|
QueryText = Utils.StringToBytes(searchText),
|
|
QueryID = UUID.Random(),
|
|
QueryStart = queryStart
|
|
}
|
|
};
|
|
|
|
Client.Network.SendPacket(find);
|
|
|
|
return find.QueryData.QueryID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search Places for parcels of land you personally own
|
|
/// </summary>
|
|
public UUID StartPlacesSearch()
|
|
{
|
|
return StartPlacesSearch(DirFindFlags.AgentOwned, ParcelCategory.Any, string.Empty, string.Empty,
|
|
UUID.Zero, UUID.Random());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Searches Places for land owned by the specified group
|
|
/// </summary>
|
|
/// <param name="groupID">ID of the group you want to receive land list for (You must be a member of the group)</param>
|
|
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
|
public UUID StartPlacesSearch(UUID groupID)
|
|
{
|
|
return StartPlacesSearch(DirFindFlags.GroupOwned, ParcelCategory.Any, string.Empty, string.Empty,
|
|
groupID, UUID.Random());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search the Places directory for parcels that are listed in search and contain the specified keywords
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing the keywords to search for</param>
|
|
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
|
public UUID StartPlacesSearch(string searchText)
|
|
{
|
|
return StartPlacesSearch(DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult,
|
|
ParcelCategory.Any, searchText, string.Empty, UUID.Zero, UUID.Random());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search Places - All Options
|
|
/// </summary>
|
|
/// <param name="findFlags">One of the Values from the DirFindFlags struct, ie: AgentOwned, GroupOwned, etc.</param>
|
|
/// <param name="searchCategory">One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer</param>
|
|
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
|
/// <param name="simulatorName">String Simulator Name to search in</param>
|
|
/// <param name="groupID">LLUID of group you want to receive results for</param>
|
|
/// <param name="transactionID">Transaction (Query) ID which can be associated with results from your request.</param>
|
|
/// <returns>Transaction (Query) ID which can be associated with results from your request.</returns>
|
|
public UUID StartPlacesSearch(DirFindFlags findFlags, ParcelCategory searchCategory, string searchText, string simulatorName,
|
|
UUID groupID, UUID transactionID)
|
|
{
|
|
PlacesQueryPacket find = new PlacesQueryPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID,
|
|
QueryID = groupID
|
|
},
|
|
TransactionData =
|
|
{
|
|
TransactionID = transactionID
|
|
},
|
|
QueryData =
|
|
{
|
|
QueryText = Utils.StringToBytes(searchText),
|
|
QueryFlags = (uint)findFlags,
|
|
Category = (sbyte)searchCategory,
|
|
SimName = Utils.StringToBytes(simulatorName)
|
|
}
|
|
};
|
|
|
|
Client.Network.SendPacket(find);
|
|
return transactionID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search All Events with specifid searchText in all categories, includes PG, Mature and Adult
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
|
/// <param name="queryStart">Each request is limited to 100 entries
|
|
/// being returned. To get the first group of entries of a request use 0,
|
|
/// from 100-199 use 100, 200-299 use 200, etc.</param>
|
|
/// <returns>UUID of query to correlate results in callback.</returns>
|
|
public UUID StartEventsSearch(string searchText, uint queryStart)
|
|
{
|
|
return StartEventsSearch(searchText, DirFindFlags.DateEvents | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult,
|
|
"u", queryStart, EventCategories.All);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search Events
|
|
/// </summary>
|
|
/// <param name="searchText">A string containing a list of keywords to search for separated by a space character</param>
|
|
/// <param name="queryFlags">One or more of the following flags: DateEvents, IncludePG, IncludeMature, IncludeAdult
|
|
/// from the <see cref="DirFindFlags"/> Enum
|
|
///
|
|
/// Multiple flags can be combined by separating the flags with the | (pipe) character</param>
|
|
/// <param name="eventDay">"u" for in-progress and upcoming events, -or- number of days since/until event is scheduled
|
|
/// For example "0" = Today, "1" = tomorrow, "2" = following day, "-1" = yesterday, etc.</param>
|
|
/// <param name="queryStart">Each request is limited to 100 entries
|
|
/// being returned. To get the first group of entries of a request use 0,
|
|
/// from 100-199 use 100, 200-299 use 200, etc.</param>
|
|
/// <param name="category">EventCategory event is listed under.</param>
|
|
/// <returns>UUID of query to correlate results in callback.</returns>
|
|
public UUID StartEventsSearch(string searchText, DirFindFlags queryFlags, string eventDay, uint queryStart, EventCategories category)
|
|
{
|
|
DirFindQueryPacket find = new DirFindQueryPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID
|
|
}
|
|
};
|
|
|
|
UUID queryID = UUID.Random();
|
|
|
|
find.QueryData.QueryID = queryID;
|
|
find.QueryData.QueryText = Utils.StringToBytes(eventDay + "|" + (int)category + "|" + searchText);
|
|
find.QueryData.QueryFlags = (uint)queryFlags;
|
|
find.QueryData.QueryStart = (int)queryStart;
|
|
|
|
Client.Network.SendPacket(find);
|
|
return queryID;
|
|
}
|
|
|
|
/// <summary>Requests Event Details</summary>
|
|
/// <param name="eventID">ID of Event returned from the <see cref="StartEventsSearch"/> method</param>
|
|
public void EventInfoRequest(uint eventID)
|
|
{
|
|
EventInfoRequestPacket find = new EventInfoRequestPacket
|
|
{
|
|
AgentData =
|
|
{
|
|
AgentID = Client.Self.AgentID,
|
|
SessionID = Client.Self.SessionID
|
|
},
|
|
EventData =
|
|
{
|
|
EventID = eventID
|
|
}
|
|
};
|
|
|
|
Client.Network.SendPacket(find);
|
|
}
|
|
#endregion
|
|
|
|
#region Blocking Functions
|
|
|
|
[Obsolete("Use the async StartPeopleSearch method instead")]
|
|
public bool PeopleSearch(DirFindFlags findFlags, string searchText, int queryStart,
|
|
int timeoutMS, out List<AgentSearchData> results)
|
|
{
|
|
AutoResetEvent searchEvent = new AutoResetEvent(false);
|
|
UUID id = UUID.Zero;
|
|
List<AgentSearchData> people = null;
|
|
|
|
EventHandler<DirPeopleReplyEventArgs> callback =
|
|
delegate(object sender, DirPeopleReplyEventArgs e)
|
|
{
|
|
if (id == e.QueryID)
|
|
{
|
|
people = e.MatchedPeople;
|
|
searchEvent.Set();
|
|
}
|
|
};
|
|
|
|
DirPeopleReply += callback;
|
|
|
|
id = StartPeopleSearch(searchText, queryStart);
|
|
searchEvent.WaitOne(timeoutMS, false);
|
|
DirPeopleReply -= callback;
|
|
|
|
results = people;
|
|
return (results != null);
|
|
}
|
|
|
|
#endregion Blocking Functions
|
|
|
|
#region Packet Handlers
|
|
|
|
/// <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 DirClassifiedReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirClassifieds != null)
|
|
{
|
|
DirClassifiedReplyPacket reply = (DirClassifiedReplyPacket)e.Packet;
|
|
List<Classified> classifieds = new List<Classified>();
|
|
|
|
foreach (DirClassifiedReplyPacket.QueryRepliesBlock block in reply.QueryReplies)
|
|
{
|
|
Classified classified = new Classified
|
|
{
|
|
CreationDate = Utils.UnixTimeToDateTime(block.CreationDate),
|
|
ExpirationDate = Utils.UnixTimeToDateTime(block.ExpirationDate),
|
|
Flags = (ClassifiedFlags)block.ClassifiedFlags,
|
|
ID = block.ClassifiedID,
|
|
Name = Utils.BytesToString(block.Name),
|
|
Price = block.PriceForListing
|
|
};
|
|
|
|
classifieds.Add(classified);
|
|
}
|
|
|
|
OnDirClassifieds(new DirClassifiedsReplyEventArgs(classifieds));
|
|
}
|
|
}
|
|
|
|
/// <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 DirLandReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirLandReply != null)
|
|
{
|
|
List<DirectoryParcel> parcelsForSale = new List<DirectoryParcel>();
|
|
DirLandReplyPacket reply = (DirLandReplyPacket)e.Packet;
|
|
|
|
foreach (DirLandReplyPacket.QueryRepliesBlock block in reply.QueryReplies)
|
|
{
|
|
DirectoryParcel dirParcel = new DirectoryParcel
|
|
{
|
|
ActualArea = block.ActualArea,
|
|
ID = block.ParcelID,
|
|
Name = Utils.BytesToString(block.Name),
|
|
SalePrice = block.SalePrice,
|
|
Auction = block.Auction,
|
|
ForSale = block.ForSale
|
|
};
|
|
|
|
parcelsForSale.Add(dirParcel);
|
|
}
|
|
OnDirLand(new DirLandReplyEventArgs(parcelsForSale));
|
|
}
|
|
}
|
|
|
|
/// <summary>Process an incoming <see cref="DirLandReplyMessage"/> event message</summary>
|
|
/// <param name="capsKey">The Unique Capabilities Key</param>
|
|
/// <param name="message">The <see cref="DirLandReplyMessage"/> event message containing the data</param>
|
|
/// <param name="simulator">The simulator the message originated from</param>
|
|
protected void DirLandReplyEventHandler(string capsKey, IMessage message, Simulator simulator)
|
|
{
|
|
if (m_DirLandReply != null)
|
|
{
|
|
List<DirectoryParcel> parcelsForSale = new List<DirectoryParcel>();
|
|
|
|
DirLandReplyMessage reply = (DirLandReplyMessage)message;
|
|
|
|
foreach (DirLandReplyMessage.QueryReply block in reply.QueryReplies)
|
|
{
|
|
DirectoryParcel dirParcel = new DirectoryParcel
|
|
{
|
|
ActualArea = block.ActualArea,
|
|
ID = block.ParcelID,
|
|
Name = block.Name,
|
|
SalePrice = block.SalePrice,
|
|
Auction = block.Auction,
|
|
ForSale = block.ForSale
|
|
};
|
|
|
|
parcelsForSale.Add(dirParcel);
|
|
}
|
|
|
|
OnDirLand(new DirLandReplyEventArgs(parcelsForSale));
|
|
}
|
|
}
|
|
|
|
/// <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 DirPeopleReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirPeople != null)
|
|
{
|
|
DirPeopleReplyPacket peopleReply = e.Packet as DirPeopleReplyPacket;
|
|
List<AgentSearchData> matches = new List<AgentSearchData>(peopleReply.QueryReplies.Length);
|
|
foreach (DirPeopleReplyPacket.QueryRepliesBlock reply in peopleReply.QueryReplies)
|
|
{
|
|
AgentSearchData searchData = new AgentSearchData
|
|
{
|
|
Online = reply.Online,
|
|
FirstName = Utils.BytesToString(reply.FirstName),
|
|
LastName = Utils.BytesToString(reply.LastName),
|
|
AgentID = reply.AgentID
|
|
};
|
|
matches.Add(searchData);
|
|
}
|
|
|
|
OnDirPeople(new DirPeopleReplyEventArgs(peopleReply.QueryData.QueryID, matches));
|
|
}
|
|
}
|
|
|
|
/// <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 DirGroupsReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirGroups != null)
|
|
{
|
|
Packet packet = e.Packet;
|
|
DirGroupsReplyPacket groupsReply = (DirGroupsReplyPacket)packet;
|
|
List<GroupSearchData> matches = new List<GroupSearchData>(groupsReply.QueryReplies.Length);
|
|
foreach (DirGroupsReplyPacket.QueryRepliesBlock reply in groupsReply.QueryReplies)
|
|
{
|
|
GroupSearchData groupsData = new GroupSearchData
|
|
{
|
|
GroupID = reply.GroupID,
|
|
GroupName = Utils.BytesToString(reply.GroupName),
|
|
Members = reply.Members
|
|
};
|
|
matches.Add(groupsData);
|
|
}
|
|
|
|
OnDirGroups(new DirGroupsReplyEventArgs(groupsReply.QueryData.QueryID, matches));
|
|
}
|
|
}
|
|
|
|
/// <summary>Process an incoming <see cref="PlacesReplyMessage"/> event message</summary>
|
|
/// <param name="capsKey">The Unique Capabilities Key</param>
|
|
/// <param name="message">The <see cref="PlacesReplyMessage"/> event message containing the data</param>
|
|
/// <param name="simulator">The simulator the message originated from</param>
|
|
protected void PlacesReplyEventHandler(string capsKey, IMessage message, Simulator simulator)
|
|
{
|
|
if (m_Places != null)
|
|
{
|
|
PlacesReplyMessage replyMessage = (PlacesReplyMessage)message;
|
|
List<PlacesSearchData> places = new List<PlacesSearchData>();
|
|
|
|
foreach (var query in replyMessage.QueryDataBlocks)
|
|
{
|
|
PlacesSearchData place = new PlacesSearchData
|
|
{
|
|
ActualArea = query.ActualArea,
|
|
BillableArea = query.BillableArea,
|
|
Desc = query.Description,
|
|
Dwell = query.Dwell,
|
|
Flags = (DirectoryManager.PlacesFlags)(byte)query.Flags,
|
|
GlobalX = query.GlobalX,
|
|
GlobalY = query.GlobalY,
|
|
GlobalZ = query.GlobalZ,
|
|
Name = query.Name,
|
|
OwnerID = query.OwnerID,
|
|
Price = query.Price,
|
|
SimName = query.SimName,
|
|
SnapshotID = query.SnapShotID,
|
|
SKU = query.ProductSku
|
|
};
|
|
places.Add(place);
|
|
}
|
|
|
|
OnPlaces(new PlacesReplyEventArgs(replyMessage.QueryID, places));
|
|
}
|
|
}
|
|
|
|
/// <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 PlacesReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_Places != null)
|
|
{
|
|
Packet packet = e.Packet;
|
|
PlacesReplyPacket placesReply = packet as PlacesReplyPacket;
|
|
List<PlacesSearchData> places = new List<PlacesSearchData>();
|
|
|
|
foreach (PlacesReplyPacket.QueryDataBlock block in placesReply.QueryData)
|
|
{
|
|
PlacesSearchData place = new PlacesSearchData
|
|
{
|
|
OwnerID = block.OwnerID,
|
|
Name = Utils.BytesToString(block.Name),
|
|
Desc = Utils.BytesToString(block.Desc),
|
|
ActualArea = block.ActualArea,
|
|
BillableArea = block.BillableArea,
|
|
Flags = (PlacesFlags)block.Flags,
|
|
GlobalX = block.GlobalX,
|
|
GlobalY = block.GlobalY,
|
|
GlobalZ = block.GlobalZ,
|
|
SimName = Utils.BytesToString(block.SimName),
|
|
SnapshotID = block.SnapshotID,
|
|
Dwell = block.Dwell,
|
|
Price = block.Price
|
|
};
|
|
|
|
places.Add(place);
|
|
}
|
|
|
|
OnPlaces(new PlacesReplyEventArgs(placesReply.TransactionData.TransactionID, places));
|
|
}
|
|
}
|
|
|
|
/// <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 EventsReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirEvents != null)
|
|
{
|
|
Packet packet = e.Packet;
|
|
DirEventsReplyPacket eventsReply = (DirEventsReplyPacket)packet;
|
|
List<EventsSearchData> matches = new List<EventsSearchData>(eventsReply.QueryReplies.Length);
|
|
|
|
foreach (DirEventsReplyPacket.QueryRepliesBlock reply in eventsReply.QueryReplies)
|
|
{
|
|
EventsSearchData eventsData = new EventsSearchData
|
|
{
|
|
Owner = reply.OwnerID,
|
|
Name = Utils.BytesToString(reply.Name),
|
|
ID = reply.EventID,
|
|
Date = Utils.BytesToString(reply.Date),
|
|
Time = reply.UnixTime,
|
|
Flags = (EventFlags)reply.EventFlags
|
|
};
|
|
matches.Add(eventsData);
|
|
}
|
|
|
|
OnDirEvents(new DirEventsReplyEventArgs(eventsReply.QueryData.QueryID, matches));
|
|
}
|
|
}
|
|
|
|
/// <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 EventInfoReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_EventInfoReply != null)
|
|
{
|
|
Packet packet = e.Packet;
|
|
EventInfoReplyPacket eventReply = (EventInfoReplyPacket)packet;
|
|
EventInfo evinfo = new EventInfo
|
|
{
|
|
ID = eventReply.EventData.EventID,
|
|
Name = Utils.BytesToString(eventReply.EventData.Name),
|
|
Desc = Utils.BytesToString(eventReply.EventData.Desc),
|
|
Amount = eventReply.EventData.Amount,
|
|
Category = (EventCategories)Utils.BytesToUInt(eventReply.EventData.Category),
|
|
Cover = eventReply.EventData.Cover,
|
|
Creator = (UUID)Utils.BytesToString(eventReply.EventData.Creator),
|
|
Date = Utils.BytesToString(eventReply.EventData.Date),
|
|
DateUTC = eventReply.EventData.DateUTC,
|
|
Duration = eventReply.EventData.Duration,
|
|
Flags = (EventFlags)eventReply.EventData.EventFlags,
|
|
SimName = Utils.BytesToString(eventReply.EventData.SimName),
|
|
GlobalPos = eventReply.EventData.GlobalPos
|
|
};
|
|
|
|
OnEventInfo(new EventInfoReplyEventArgs(evinfo));
|
|
}
|
|
}
|
|
|
|
/// <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 DirPlacesReplyHandler(object sender, PacketReceivedEventArgs e)
|
|
{
|
|
if (m_DirPlaces != null)
|
|
{
|
|
Packet packet = e.Packet;
|
|
DirPlacesReplyPacket reply = (DirPlacesReplyPacket)packet;
|
|
List<DirectoryParcel> result = reply.QueryReplies.Select(t => new DirectoryParcel
|
|
{
|
|
ID = t.ParcelID,
|
|
Name = Utils.BytesToString(t.Name),
|
|
Dwell = t.Dwell,
|
|
Auction = t.Auction,
|
|
ForSale = t.ForSale
|
|
})
|
|
.ToList();
|
|
|
|
OnDirPlaces(new DirPlacesReplyEventArgs(reply.QueryData[0].QueryID, result));
|
|
}
|
|
}
|
|
|
|
#endregion Packet Handlers
|
|
}
|
|
|
|
#region DirectoryManager EventArgs Classes
|
|
|
|
/// <summary>Contains the Event data returned from the data server from an EventInfoRequest</summary>
|
|
public class EventInfoReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>
|
|
/// A single EventInfo object containing the details of an event
|
|
/// </summary>
|
|
public DirectoryManager.EventInfo MatchedEvent { get; }
|
|
|
|
/// <summary>Construct a new instance of the EventInfoReplyEventArgs class</summary>
|
|
/// <param name="matchedEvent">A single EventInfo object containing the details of an event</param>
|
|
public EventInfoReplyEventArgs(DirectoryManager.EventInfo matchedEvent)
|
|
{
|
|
this.MatchedEvent = matchedEvent;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the "Event" detail data returned from the data server</summary>
|
|
public class DirEventsReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>The ID returned by <see cref="DirectoryManager.StartEventsSearch"/></summary>
|
|
public UUID QueryID { get; }
|
|
|
|
/// <summary>A list of "Events" returned by the data server</summary>
|
|
public List<DirectoryManager.EventsSearchData> MatchedEvents { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirEventsReplyEventArgs class</summary>
|
|
/// <param name="queryID">The ID of the query returned by the data server.
|
|
/// This will correlate to the ID returned by the <see cref="StartEventsSearch"/> method</param>
|
|
/// <param name="matchedEvents">A list containing the "Events" returned by the search query</param>
|
|
public DirEventsReplyEventArgs(UUID queryID, List<DirectoryManager.EventsSearchData> matchedEvents)
|
|
{
|
|
this.QueryID = queryID;
|
|
this.MatchedEvents = matchedEvents;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the "Event" list data returned from the data server</summary>
|
|
public class PlacesReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>The ID returned by <see cref="DirectoryManager.StartPlacesSearch"/></summary>
|
|
public UUID QueryID { get; }
|
|
|
|
/// <summary>A list of "Places" returned by the data server</summary>
|
|
public List<DirectoryManager.PlacesSearchData> MatchedPlaces { get; }
|
|
|
|
/// <summary>Construct a new instance of PlacesReplyEventArgs class</summary>
|
|
/// <param name="queryID">The ID of the query returned by the data server.
|
|
/// This will correlate to the ID returned by the <see cref="StartPlacesSearch"/> method</param>
|
|
/// <param name="matchedPlaces">A list containing the "Places" returned by the data server query</param>
|
|
public PlacesReplyEventArgs(UUID queryID, List<DirectoryManager.PlacesSearchData> matchedPlaces)
|
|
{
|
|
this.QueryID = queryID;
|
|
this.MatchedPlaces = matchedPlaces;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the places data returned from the data server</summary>
|
|
public class DirPlacesReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>The ID returned by <see cref="DirectoryManager.StartDirPlacesSearch"/></summary>
|
|
public UUID QueryID { get; }
|
|
|
|
/// <summary>A list containing Places data returned by the data server</summary>
|
|
public List<DirectoryManager.DirectoryParcel> MatchedParcels { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirPlacesReplyEventArgs class</summary>
|
|
/// <param name="queryID">The ID of the query returned by the data server.
|
|
/// This will correlate to the ID returned by the <see cref="StartDirPlacesSearch"/> method</param>
|
|
/// <param name="matchedParcels">A list containing land data returned by the data server</param>
|
|
public DirPlacesReplyEventArgs(UUID queryID, List<DirectoryManager.DirectoryParcel> matchedParcels)
|
|
{
|
|
this.QueryID = queryID;
|
|
this.MatchedParcels = matchedParcels;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the classified data returned from the data server</summary>
|
|
public class DirClassifiedsReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>A list containing Classified Ads returned by the data server</summary>
|
|
public List<DirectoryManager.Classified> Classifieds { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirClassifiedsReplyEventArgs class</summary>
|
|
/// <param name="classifieds">A list of classified ad data returned from the data server</param>
|
|
public DirClassifiedsReplyEventArgs(List<DirectoryManager.Classified> classifieds)
|
|
{
|
|
this.Classifieds = classifieds;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the group data returned from the data server</summary>
|
|
public class DirGroupsReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>The ID returned by <see cref="DirectoryManager.StartGroupSearch"/></summary>
|
|
public UUID QueryID { get; }
|
|
|
|
/// <summary>A list containing Groups data returned by the data server</summary>
|
|
public List<DirectoryManager.GroupSearchData> MatchedGroups { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirGroupsReplyEventArgs class</summary>
|
|
/// <param name="queryID">The ID of the query returned by the data server.
|
|
/// This will correlate to the ID returned by the <see cref="StartGroupSearch"/> method</param>
|
|
/// <param name="matchedGroups">A list of groups data returned by the data server</param>
|
|
public DirGroupsReplyEventArgs(UUID queryID, List<DirectoryManager.GroupSearchData> matchedGroups)
|
|
{
|
|
this.QueryID = queryID;
|
|
this.MatchedGroups = matchedGroups;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the people data returned from the data server</summary>
|
|
public class DirPeopleReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>The ID returned by <see cref="DirectoryManager.StartPeopleSearch"/></summary>
|
|
public UUID QueryID { get; }
|
|
|
|
/// <summary>A list containing People data returned by the data server</summary>
|
|
public List<DirectoryManager.AgentSearchData> MatchedPeople { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirPeopleReplyEventArgs class</summary>
|
|
/// <param name="queryID">The ID of the query returned by the data server.
|
|
/// This will correlate to the ID returned by the <see cref="StartPeopleSearch"/> method</param>
|
|
/// <param name="matchedPeople">A list of people data returned by the data server</param>
|
|
public DirPeopleReplyEventArgs(UUID queryID, List<DirectoryManager.AgentSearchData> matchedPeople)
|
|
{
|
|
this.QueryID = queryID;
|
|
this.MatchedPeople = matchedPeople;
|
|
}
|
|
}
|
|
|
|
/// <summary>Contains the land sales data returned from the data server</summary>
|
|
public class DirLandReplyEventArgs : EventArgs
|
|
{
|
|
/// <summary>A list containing land forsale data returned by the data server</summary>
|
|
public List<DirectoryManager.DirectoryParcel> DirParcels { get; }
|
|
|
|
/// <summary>Construct a new instance of the DirLandReplyEventArgs class</summary>
|
|
/// <param name="dirParcels">A list of parcels for sale returned by the data server</param>
|
|
public DirLandReplyEventArgs(List<DirectoryManager.DirectoryParcel> dirParcels)
|
|
{
|
|
this.DirParcels = dirParcels;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|