/* * Copyright (c) 2006-2014, openmetaverse.org * 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.org 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.Collections.Generic; using System.Text; using OpenMetaverse.Http; using OpenMetaverse.Packets; using OpenMetaverse.Interfaces; using OpenMetaverse.Messages.Linden; using OpenMetaverse.StructuredData; namespace OpenMetaverse { #region Structs /// Information about agents display name public class AgentDisplayName { /// Agent UUID public UUID ID; /// Username public string UserName; /// Display name public string DisplayName; /// First name (legacy) public string LegacyFirstName; /// Last name (legacy) public string LegacyLastName; /// Full name (legacy) public string LegacyFullName { get { return string.Format("{0} {1}", LegacyFirstName, LegacyLastName); } } /// Is display name default display name public bool IsDefaultDisplayName; /// Cache display name until public DateTime NextUpdate; /// Last updated timestamp public DateTime Updated; /// /// Creates AgentDisplayName object from OSD /// /// Incoming OSD data /// AgentDisplayName object public static AgentDisplayName FromOSD(OSD data) { AgentDisplayName ret = new AgentDisplayName(); OSDMap map = (OSDMap)data; ret.ID = map["id"]; ret.UserName = map["username"]; ret.DisplayName = map["display_name"]; ret.LegacyFirstName = map["legacy_first_name"]; ret.LegacyLastName = map["legacy_last_name"]; ret.IsDefaultDisplayName = map["is_display_name_default"]; ret.NextUpdate = map["display_name_next_update"]; ret.Updated = map["last_updated"]; return ret; } /// /// Return object as OSD map /// /// OSD containing agent's display name data public OSD GetOSD() { OSDMap map = new OSDMap(); map["id"] = ID; map["username"] = UserName; map["display_name"] = DisplayName; map["legacy_first_name"] = LegacyFirstName; map["legacy_last_name"] = LegacyLastName; map["is_display_name_default"] = IsDefaultDisplayName; map["display_name_next_update"] = NextUpdate; map["last_updated"] = Updated; return map; } public override string ToString() { return Helpers.StructToString(this); } } /// /// Holds group information for Avatars such as those you might find in a profile /// public struct AvatarGroup { /// true of Avatar accepts group notices public bool AcceptNotices; /// Groups Key public UUID GroupID; /// Texture Key for groups insignia public UUID GroupInsigniaID; /// Name of the group public string GroupName; /// Powers avatar has in the group public GroupPowers GroupPowers; /// Avatars Currently selected title public string GroupTitle; /// true of Avatar has chosen to list this in their profile public bool ListInProfile; } /// /// Contains an animation currently being played by an agent /// public struct Animation { /// The ID of the animation asset public UUID AnimationID; /// A number to indicate start order of currently playing animations /// On Linden Grids this number is unique per region, with OpenSim it is per client public int AnimationSequence; /// public UUID AnimationSourceObjectID; } /// /// Holds group information on an individual profile pick /// public struct ProfilePick { public UUID PickID; public UUID CreatorID; public bool TopPick; public UUID ParcelID; public string Name; public string Desc; public UUID SnapshotID; public string User; public string OriginalName; public string SimName; public Vector3d PosGlobal; public int SortOrder; public bool Enabled; } public struct ClassifiedAd { public UUID ClassifiedID; public uint Catagory; public UUID ParcelID; public uint ParentEstate; public UUID SnapShotID; public Vector3d Position; public byte ClassifiedFlags; public int Price; public string Name; public string Desc; } #endregion /// /// Retrieve friend status notifications, and retrieve avatar names and /// profiles /// public class AvatarManager { const int MAX_UUIDS_PER_PACKET = 100; #region Events /// The event subscribers, null of no subscribers private EventHandler m_AvatarAnimation; ///Raises the AvatarAnimation Event /// An AvatarAnimationEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarAnimation(AvatarAnimationEventArgs e) { EventHandler handler = m_AvatarAnimation; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarAnimationLock = new object(); /// Raised when the simulator sends us data containing /// an agents animation playlist public event EventHandler AvatarAnimation { add { lock (m_AvatarAnimationLock) { m_AvatarAnimation += value; } } remove { lock (m_AvatarAnimationLock) { m_AvatarAnimation -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarAppearance; ///Raises the AvatarAppearance Event /// A AvatarAppearanceEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarAppearance(AvatarAppearanceEventArgs e) { EventHandler handler = m_AvatarAppearance; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarAppearanceLock = new object(); /// Raised when the simulator sends us data containing /// the appearance information for an agent public event EventHandler AvatarAppearance { add { lock (m_AvatarAppearanceLock) { m_AvatarAppearance += value; } } remove { lock (m_AvatarAppearanceLock) { m_AvatarAppearance -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_UUIDNameReply; ///Raises the UUIDNameReply Event /// A UUIDNameReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnUUIDNameReply(UUIDNameReplyEventArgs e) { EventHandler handler = m_UUIDNameReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_UUIDNameReplyLock = new object(); /// Raised when the simulator sends us data containing /// agent names/id values public event EventHandler UUIDNameReply { add { lock (m_UUIDNameReplyLock) { m_UUIDNameReply += value; } } remove { lock (m_UUIDNameReplyLock) { m_UUIDNameReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarInterestsReply; ///Raises the AvatarInterestsReply Event /// A AvatarInterestsReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarInterestsReply(AvatarInterestsReplyEventArgs e) { EventHandler handler = m_AvatarInterestsReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarInterestsReplyLock = new object(); /// Raised when the simulator sends us data containing /// the interests listed in an agents profile public event EventHandler AvatarInterestsReply { add { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply += value; } } remove { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarPropertiesReply; ///Raises the AvatarPropertiesReply Event /// A AvatarPropertiesReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarPropertiesReply(AvatarPropertiesReplyEventArgs e) { EventHandler handler = m_AvatarPropertiesReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarPropertiesReplyLock = new object(); /// Raised when the simulator sends us data containing /// profile property information for an agent public event EventHandler AvatarPropertiesReply { add { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply += value; } } remove { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarGroupsReply; ///Raises the AvatarGroupsReply Event /// A AvatarGroupsReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarGroupsReply(AvatarGroupsReplyEventArgs e) { EventHandler handler = m_AvatarGroupsReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarGroupsReplyLock = new object(); /// Raised when the simulator sends us data containing /// the group membership an agent is a member of public event EventHandler AvatarGroupsReply { add { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply += value; } } remove { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarPickerReply; ///Raises the AvatarPickerReply Event /// A AvatarPickerReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarPickerReply(AvatarPickerReplyEventArgs e) { EventHandler handler = m_AvatarPickerReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarPickerReplyLock = new object(); /// Raised when the simulator sends us data containing /// name/id pair public event EventHandler AvatarPickerReply { add { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply += value; } } remove { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_ViewerEffectPointAt; ///Raises the ViewerEffectPointAt Event /// A ViewerEffectPointAtEventArgs object containing /// the data sent from the simulator protected virtual void OnViewerEffectPointAt(ViewerEffectPointAtEventArgs e) { EventHandler handler = m_ViewerEffectPointAt; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_ViewerEffectPointAtLock = new object(); /// Raised when the simulator sends us data containing /// the objects and effect when an agent is pointing at public event EventHandler ViewerEffectPointAt { add { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt += value; } } remove { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_ViewerEffectLookAt; ///Raises the ViewerEffectLookAt Event /// A ViewerEffectLookAtEventArgs object containing /// the data sent from the simulator protected virtual void OnViewerEffectLookAt(ViewerEffectLookAtEventArgs e) { EventHandler handler = m_ViewerEffectLookAt; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_ViewerEffectLookAtLock = new object(); /// Raised when the simulator sends us data containing /// the objects and effect when an agent is looking at public event EventHandler ViewerEffectLookAt { add { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt += value; } } remove { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_ViewerEffect; ///Raises the ViewerEffect Event /// A ViewerEffectEventArgs object containing /// the data sent from the simulator protected virtual void OnViewerEffect(ViewerEffectEventArgs e) { EventHandler handler = m_ViewerEffect; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_ViewerEffectLock = new object(); /// Raised when the simulator sends us data containing /// an agents viewer effect information public event EventHandler ViewerEffect { add { lock (m_ViewerEffectLock) { m_ViewerEffect += value; } } remove { lock (m_ViewerEffectLock) { m_ViewerEffect -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarPicksReply; ///Raises the AvatarPicksReply Event /// A AvatarPicksReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarPicksReply(AvatarPicksReplyEventArgs e) { EventHandler handler = m_AvatarPicksReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarPicksReplyLock = new object(); /// Raised when the simulator sends us data containing /// the top picks from an agents profile public event EventHandler AvatarPicksReply { add { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply += value; } } remove { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_PickInfoReply; ///Raises the PickInfoReply Event /// A PickInfoReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnPickInfoReply(PickInfoReplyEventArgs e) { EventHandler handler = m_PickInfoReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_PickInfoReplyLock = new object(); /// Raised when the simulator sends us data containing /// the Pick details public event EventHandler PickInfoReply { add { lock (m_PickInfoReplyLock) { m_PickInfoReply += value; } } remove { lock (m_PickInfoReplyLock) { m_PickInfoReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_AvatarClassifiedReply; ///Raises the AvatarClassifiedReply Event /// A AvatarClassifiedReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnAvatarClassifiedReply(AvatarClassifiedReplyEventArgs e) { EventHandler handler = m_AvatarClassifiedReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_AvatarClassifiedReplyLock = new object(); /// Raised when the simulator sends us data containing /// the classified ads an agent has placed public event EventHandler AvatarClassifiedReply { add { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply += value; } } remove { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_ClassifiedInfoReply; ///Raises the ClassifiedInfoReply Event /// A ClassifiedInfoReplyEventArgs object containing /// the data sent from the simulator protected virtual void OnClassifiedInfoReply(ClassifiedInfoReplyEventArgs e) { EventHandler handler = m_ClassifiedInfoReply; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_ClassifiedInfoReplyLock = new object(); /// Raised when the simulator sends us data containing /// the details of a classified ad public event EventHandler ClassifiedInfoReply { add { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply += value; } } remove { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply -= value; } } } /// The event subscribers, null of no subscribers private EventHandler m_DisplayNameUpdate; ///Raises the DisplayNameUpdate Event /// A DisplayNameUpdateEventArgs object containing /// the data sent from the simulator protected virtual void OnDisplayNameUpdate(DisplayNameUpdateEventArgs e) { EventHandler handler = m_DisplayNameUpdate; if (handler != null) handler(this, e); } /// Thread sync lock object private readonly object m_DisplayNameUpdateLock = new object(); /// Raised when the simulator sends us data containing /// the details of display name change public event EventHandler DisplayNameUpdate { add { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate += value; } } remove { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate -= value; } } } #endregion Events #region Delegates /// /// Callback giving results when fetching display names /// /// If the request was successful /// Array of display names /// Array of UUIDs that could not be fetched public delegate void DisplayNamesCallback(bool success, AgentDisplayName[] names, UUID[] badIDs); #endregion Delegates private GridClient Client; /// /// Represents other avatars /// /// public AvatarManager(GridClient client) { Client = client; // Avatar appearance callback Client.Network.RegisterCallback(PacketType.AvatarAppearance, AvatarAppearanceHandler); // Avatar profile callbacks Client.Network.RegisterCallback(PacketType.AvatarPropertiesReply, AvatarPropertiesHandler); // Client.Network.RegisterCallback(PacketType.AvatarStatisticsReply, AvatarStatisticsHandler); Client.Network.RegisterCallback(PacketType.AvatarInterestsReply, AvatarInterestsHandler); // Avatar group callback Client.Network.RegisterCallback(PacketType.AvatarGroupsReply, AvatarGroupsReplyHandler); Client.Network.RegisterEventCallback("AgentGroupDataUpdate", AvatarGroupsReplyMessageHandler); Client.Network.RegisterEventCallback("AvatarGroupsReply", AvatarGroupsReplyMessageHandler); // Viewer effect callback Client.Network.RegisterCallback(PacketType.ViewerEffect, ViewerEffectHandler); // Other callbacks Client.Network.RegisterCallback(PacketType.UUIDNameReply, UUIDNameReplyHandler); Client.Network.RegisterCallback(PacketType.AvatarPickerReply, AvatarPickerReplyHandler); Client.Network.RegisterCallback(PacketType.AvatarAnimation, AvatarAnimationHandler); // Picks callbacks Client.Network.RegisterCallback(PacketType.AvatarPicksReply, AvatarPicksReplyHandler); Client.Network.RegisterCallback(PacketType.PickInfoReply, PickInfoReplyHandler); // Classifieds callbacks Client.Network.RegisterCallback(PacketType.AvatarClassifiedReply, AvatarClassifiedReplyHandler); Client.Network.RegisterCallback(PacketType.ClassifiedInfoReply, ClassifiedInfoReplyHandler); Client.Network.RegisterEventCallback("DisplayNameUpdate", DisplayNameUpdateMessageHandler); } /// Tracks the specified avatar on your map /// Avatar ID to track public void RequestTrackAgent(UUID preyID) { TrackAgentPacket p = new TrackAgentPacket(); p.AgentData.AgentID = Client.Self.AgentID; p.AgentData.SessionID = Client.Self.SessionID; p.TargetData.PreyID = preyID; Client.Network.SendPacket(p); } /// /// Request a single avatar name /// /// The avatar key to retrieve a name for public void RequestAvatarName(UUID id) { UUIDNameRequestPacket request = new UUIDNameRequestPacket(); request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[1]; request.UUIDNameBlock[0] = new UUIDNameRequestPacket.UUIDNameBlockBlock(); request.UUIDNameBlock[0].ID = id; Client.Network.SendPacket(request); } /// /// Request a list of avatar names /// /// The avatar keys to retrieve names for public void RequestAvatarNames(List ids) { int m = MAX_UUIDS_PER_PACKET; int n = ids.Count / m; // Number of full requests to make int i = 0; UUIDNameRequestPacket request; for (int j = 0; j < n; j++) { request = new UUIDNameRequestPacket(); request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[m]; for (; i < (j + 1) * m; i++) { request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock(); request.UUIDNameBlock[i % m].ID = ids[i]; } Client.Network.SendPacket(request); } // Get any remaining names after left after the full requests if (ids.Count > n * m) { request = new UUIDNameRequestPacket(); request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.Count - n * m]; for (; i < ids.Count; i++) { request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock(); request.UUIDNameBlock[i % m].ID = ids[i]; } Client.Network.SendPacket(request); } } /// /// Check if Display Names functionality is available /// /// True if Display name functionality is available public bool DisplayNamesAvailable() { return (Client.Network.CurrentSim != null && Client.Network.CurrentSim.Caps != null) && Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames") != null; } /// /// Request retrieval of display names (max 90 names per request) /// /// List of UUIDs to lookup /// Callback to report result of the operation public void GetDisplayNames(List ids, DisplayNamesCallback callback) { if (!DisplayNamesAvailable() || ids.Count == 0) { callback(false, null, null); } StringBuilder query = new StringBuilder(); for (int i = 0; i < ids.Count && i < 90; i++) { query.AppendFormat("ids={0}", ids[i]); if (i < ids.Count - 1) { query.Append("&"); } } Uri uri = new Uri(Client.Network.CurrentSim.Caps.CapabilityURI("GetDisplayNames").AbsoluteUri + "/?" + query); CapsClient cap = new CapsClient(uri); cap.OnComplete += (CapsClient client, OSD result, Exception error) => { try { if (error != null) throw error; GetDisplayNamesMessage msg = new GetDisplayNamesMessage(); msg.Deserialize((OSDMap)result); callback(true, msg.Agents, msg.BadIDs); } catch (Exception ex) { Logger.Log("Failed to call GetDisplayNames capability: ", Helpers.LogLevel.Warning, Client, ex); callback(false, null, null); } }; cap.BeginGetResponse(null, String.Empty, Client.Settings.CAPS_TIMEOUT); } /// /// Start a request for Avatar Properties /// /// public void RequestAvatarProperties(UUID avatarid) { AvatarPropertiesRequestPacket aprp = new AvatarPropertiesRequestPacket(); aprp.AgentData.AgentID = Client.Self.AgentID; aprp.AgentData.SessionID = Client.Self.SessionID; aprp.AgentData.AvatarID = avatarid; Client.Network.SendPacket(aprp); } /// /// Search for an avatar (first name, last name) /// /// The name to search for /// An ID to associate with this query public void RequestAvatarNameSearch(string name, UUID queryID) { AvatarPickerRequestPacket aprp = new AvatarPickerRequestPacket(); aprp.AgentData.AgentID = Client.Self.AgentID; aprp.AgentData.SessionID = Client.Self.SessionID; aprp.AgentData.QueryID = queryID; aprp.Data.Name = Utils.StringToBytes(name); Client.Network.SendPacket(aprp); } /// /// Start a request for Avatar Picks /// /// UUID of the avatar public void RequestAvatarPicks(UUID avatarid) { GenericMessagePacket gmp = new GenericMessagePacket(); gmp.AgentData.AgentID = Client.Self.AgentID; gmp.AgentData.SessionID = Client.Self.SessionID; gmp.AgentData.TransactionID = UUID.Zero; gmp.MethodData.Method = Utils.StringToBytes("avatarpicksrequest"); gmp.MethodData.Invoice = UUID.Zero; gmp.ParamList = new GenericMessagePacket.ParamListBlock[1]; gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString()); Client.Network.SendPacket(gmp); } /// /// Start a request for Avatar Classifieds /// /// UUID of the avatar public void RequestAvatarClassified(UUID avatarid) { GenericMessagePacket gmp = new GenericMessagePacket(); gmp.AgentData.AgentID = Client.Self.AgentID; gmp.AgentData.SessionID = Client.Self.SessionID; gmp.AgentData.TransactionID = UUID.Zero; gmp.MethodData.Method = Utils.StringToBytes("avatarclassifiedsrequest"); gmp.MethodData.Invoice = UUID.Zero; gmp.ParamList = new GenericMessagePacket.ParamListBlock[1]; gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString()); Client.Network.SendPacket(gmp); } /// /// Start a request for details of a specific profile pick /// /// UUID of the avatar /// UUID of the profile pick public void RequestPickInfo(UUID avatarid, UUID pickid) { GenericMessagePacket gmp = new GenericMessagePacket(); gmp.AgentData.AgentID = Client.Self.AgentID; gmp.AgentData.SessionID = Client.Self.SessionID; gmp.AgentData.TransactionID = UUID.Zero; gmp.MethodData.Method = Utils.StringToBytes("pickinforequest"); gmp.MethodData.Invoice = UUID.Zero; gmp.ParamList = new GenericMessagePacket.ParamListBlock[2]; gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString()); gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[1].Parameter = Utils.StringToBytes(pickid.ToString()); Client.Network.SendPacket(gmp); } /// /// Start a request for details of a specific profile classified /// /// UUID of the avatar /// UUID of the profile classified public void RequestClassifiedInfo(UUID avatarid, UUID classifiedid) { GenericMessagePacket gmp = new GenericMessagePacket(); gmp.AgentData.AgentID = Client.Self.AgentID; gmp.AgentData.SessionID = Client.Self.SessionID; gmp.AgentData.TransactionID = UUID.Zero; gmp.MethodData.Method = Utils.StringToBytes("classifiedinforequest"); gmp.MethodData.Invoice = UUID.Zero; gmp.ParamList = new GenericMessagePacket.ParamListBlock[2]; gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[0].Parameter = Utils.StringToBytes(avatarid.ToString()); gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock(); gmp.ParamList[1].Parameter = Utils.StringToBytes(classifiedid.ToString()); Client.Network.SendPacket(gmp); } #region Packet Handlers /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void UUIDNameReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_UUIDNameReply != null) { Packet packet = e.Packet; Dictionary names = new Dictionary(); UUIDNameReplyPacket reply = (UUIDNameReplyPacket)packet; foreach (UUIDNameReplyPacket.UUIDNameBlockBlock block in reply.UUIDNameBlock) { names[block.ID] = Utils.BytesToString(block.FirstName) + " " + Utils.BytesToString(block.LastName); } OnUUIDNameReply(new UUIDNameReplyEventArgs(names)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarAnimationHandler(object sender, PacketReceivedEventArgs e) { Packet packet = e.Packet; AvatarAnimationPacket data = (AvatarAnimationPacket)packet; List signaledAnimations = new List(data.AnimationList.Length); for (int i = 0; i < data.AnimationList.Length; i++) { Animation animation = new Animation(); animation.AnimationID = data.AnimationList[i].AnimID; animation.AnimationSequence = data.AnimationList[i].AnimSequenceID; if (i < data.AnimationSourceList.Length) { animation.AnimationSourceObjectID = data.AnimationSourceList[i].ObjectID; } signaledAnimations.Add(animation); } Avatar avatar = e.Simulator.ObjectsAvatars.Find(avi => avi.ID == data.Sender.ID); if (avatar != null) { avatar.Animations = signaledAnimations; } OnAvatarAnimation(new AvatarAnimationEventArgs(data.Sender.ID, signaledAnimations)); } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarAppearanceHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarAppearance != null || Client.Settings.AVATAR_TRACKING) { Packet packet = e.Packet; Simulator simulator = e.Simulator; AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet; List visualParams = new List(); foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam) { visualParams.Add(block.ParamValue); } Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(appearance.ObjectData.TextureEntry, 0, appearance.ObjectData.TextureEntry.Length); Primitive.TextureEntryFace defaultTexture = textureEntry.DefaultTexture; Primitive.TextureEntryFace[] faceTextures = textureEntry.FaceTextures; byte appearanceVersion = 0; int COFVersion = 0; AppearanceFlags appearanceFlags = 0; if (appearance.AppearanceData != null && appearance.AppearanceData.Length > 0) { appearanceVersion = appearance.AppearanceData[0].AppearanceVersion; COFVersion = appearance.AppearanceData[0].CofVersion; appearanceFlags = (AppearanceFlags)appearance.AppearanceData[0].Flags; } Avatar av = simulator.ObjectsAvatars.Find((Avatar a) => { return a.ID == appearance.Sender.ID; }); if (av != null) { av.Textures = textureEntry; av.VisualParameters = visualParams.ToArray(); av.AppearanceVersion = appearanceVersion; av.COFVersion = COFVersion; av.AppearanceFlags = appearanceFlags; } OnAvatarAppearance(new AvatarAppearanceEventArgs(simulator, appearance.Sender.ID, appearance.Sender.IsTrial, defaultTexture, faceTextures, visualParams, appearanceVersion, COFVersion, appearanceFlags)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarPropertiesHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarPropertiesReply != null) { Packet packet = e.Packet; AvatarPropertiesReplyPacket reply = (AvatarPropertiesReplyPacket)packet; Avatar.AvatarProperties properties = new Avatar.AvatarProperties(); properties.ProfileImage = reply.PropertiesData.ImageID; properties.FirstLifeImage = reply.PropertiesData.FLImageID; properties.Partner = reply.PropertiesData.PartnerID; properties.AboutText = Utils.BytesToString(reply.PropertiesData.AboutText); properties.FirstLifeText = Utils.BytesToString(reply.PropertiesData.FLAboutText); properties.BornOn = Utils.BytesToString(reply.PropertiesData.BornOn); //properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember); uint charter = Utils.BytesToUInt(reply.PropertiesData.CharterMember); if (charter == 0) { properties.CharterMember = "Resident"; } else if (charter == 2) { properties.CharterMember = "Charter"; } else if (charter == 3) { properties.CharterMember = "Linden"; } else { properties.CharterMember = Utils.BytesToString(reply.PropertiesData.CharterMember); } properties.Flags = (ProfileFlags)reply.PropertiesData.Flags; properties.ProfileURL = Utils.BytesToString(reply.PropertiesData.ProfileURL); OnAvatarPropertiesReply(new AvatarPropertiesReplyEventArgs(reply.AgentData.AvatarID, properties)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarInterestsHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarInterestsReply != null) { Packet packet = e.Packet; AvatarInterestsReplyPacket airp = (AvatarInterestsReplyPacket)packet; Avatar.Interests interests = new Avatar.Interests(); interests.WantToMask = airp.PropertiesData.WantToMask; interests.WantToText = Utils.BytesToString(airp.PropertiesData.WantToText); interests.SkillsMask = airp.PropertiesData.SkillsMask; interests.SkillsText = Utils.BytesToString(airp.PropertiesData.SkillsText); interests.LanguagesText = Utils.BytesToString(airp.PropertiesData.LanguagesText); OnAvatarInterestsReply(new AvatarInterestsReplyEventArgs(airp.AgentData.AvatarID, interests)); } } /// /// EQ Message fired when someone nearby changes their display name /// /// The message key /// the IMessage object containing the deserialized data sent from the simulator /// The which originated the packet protected void DisplayNameUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator) { if (m_DisplayNameUpdate != null) { DisplayNameUpdateMessage msg = (DisplayNameUpdateMessage)message; OnDisplayNameUpdate(new DisplayNameUpdateEventArgs(msg.OldDisplayName, msg.DisplayName)); } } /// /// Crossed region handler for message that comes across the EventQueue. Sent to an agent /// when the agent crosses a sim border into a new region. /// /// The message key /// the IMessage object containing the deserialized data sent from the simulator /// The which originated the packet protected void AvatarGroupsReplyMessageHandler(string capsKey, IMessage message, Simulator simulator) { AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message; List avatarGroups = new List(msg.GroupDataBlock.Length); for (int i = 0; i < msg.GroupDataBlock.Length; i++) { AvatarGroup avatarGroup = new AvatarGroup(); avatarGroup.AcceptNotices = msg.GroupDataBlock[i].AcceptNotices; avatarGroup.GroupID = msg.GroupDataBlock[i].GroupID; avatarGroup.GroupInsigniaID = msg.GroupDataBlock[i].GroupInsigniaID; avatarGroup.GroupName = msg.GroupDataBlock[i].GroupName; avatarGroup.GroupPowers = msg.GroupDataBlock[i].GroupPowers; avatarGroup.ListInProfile = msg.NewGroupDataBlock[i].ListInProfile; avatarGroups.Add(avatarGroup); } OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(msg.AgentID, avatarGroups)); } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarGroupsReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarGroupsReply != null) { Packet packet = e.Packet; AvatarGroupsReplyPacket groups = (AvatarGroupsReplyPacket)packet; List avatarGroups = new List(groups.GroupData.Length); for (int i = 0; i < groups.GroupData.Length; i++) { AvatarGroup avatarGroup = new AvatarGroup(); avatarGroup.AcceptNotices = groups.GroupData[i].AcceptNotices; avatarGroup.GroupID = groups.GroupData[i].GroupID; avatarGroup.GroupInsigniaID = groups.GroupData[i].GroupInsigniaID; avatarGroup.GroupName = Utils.BytesToString(groups.GroupData[i].GroupName); avatarGroup.GroupPowers = (GroupPowers)groups.GroupData[i].GroupPowers; avatarGroup.GroupTitle = Utils.BytesToString(groups.GroupData[i].GroupTitle); avatarGroup.ListInProfile = groups.NewGroupData.ListInProfile; avatarGroups.Add(avatarGroup); } OnAvatarGroupsReply(new AvatarGroupsReplyEventArgs(groups.AgentData.AvatarID, avatarGroups)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarPickerReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarPickerReply != null) { Packet packet = e.Packet; AvatarPickerReplyPacket reply = (AvatarPickerReplyPacket)packet; Dictionary avatars = new Dictionary(); foreach (AvatarPickerReplyPacket.DataBlock block in reply.Data) { avatars[block.AvatarID] = Utils.BytesToString(block.FirstName) + " " + Utils.BytesToString(block.LastName); } OnAvatarPickerReply(new AvatarPickerReplyEventArgs(reply.AgentData.QueryID, avatars)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void ViewerEffectHandler(object sender, PacketReceivedEventArgs e) { Packet packet = e.Packet; ViewerEffectPacket effect = (ViewerEffectPacket)packet; foreach (ViewerEffectPacket.EffectBlock block in effect.Effect) { EffectType type = (EffectType)block.Type; // Each ViewerEffect type uses it's own custom binary format for additional data. Fun eh? switch (type) { case EffectType.Text: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.Icon: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.Connector: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.FlexibleObject: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.AnimalControls: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.AnimationObject: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.Cloth: Logger.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning, Client); break; case EffectType.Glow: Logger.Log("Received a Glow ViewerEffect which is not implemented yet", Helpers.LogLevel.Warning, Client); break; case EffectType.Beam: case EffectType.Point: case EffectType.Trail: case EffectType.Sphere: case EffectType.Spiral: case EffectType.Edit: if (m_ViewerEffect != null) { if (block.TypeData.Length == 56) { UUID sourceAvatar = new UUID(block.TypeData, 0); UUID targetObject = new UUID(block.TypeData, 16); Vector3d targetPos = new Vector3d(block.TypeData, 32); OnViewerEffect(new ViewerEffectEventArgs(type, sourceAvatar, targetObject, targetPos, block.Duration, block.ID)); } else { Logger.Log("Received a " + type.ToString() + " ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client); } } break; case EffectType.LookAt: if (m_ViewerEffectLookAt != null) { if (block.TypeData.Length == 57) { UUID sourceAvatar = new UUID(block.TypeData, 0); UUID targetObject = new UUID(block.TypeData, 16); Vector3d targetPos = new Vector3d(block.TypeData, 32); LookAtType lookAt = (LookAtType)block.TypeData[56]; OnViewerEffectLookAt(new ViewerEffectLookAtEventArgs(sourceAvatar, targetObject, targetPos, lookAt, block.Duration, block.ID)); } else { Logger.Log("Received a LookAt ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client); } } break; case EffectType.PointAt: if (m_ViewerEffectPointAt != null) { if (block.TypeData.Length == 57) { UUID sourceAvatar = new UUID(block.TypeData, 0); UUID targetObject = new UUID(block.TypeData, 16); Vector3d targetPos = new Vector3d(block.TypeData, 32); PointAtType pointAt = (PointAtType)block.TypeData[56]; OnViewerEffectPointAt(new ViewerEffectPointAtEventArgs(e.Simulator, sourceAvatar, targetObject, targetPos, pointAt, block.Duration, block.ID)); } else { Logger.Log("Received a PointAt ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning, Client); } } break; default: Logger.Log("Received a ViewerEffect with an unknown type " + type, Helpers.LogLevel.Warning, Client); break; } } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarPicksReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarPicksReply == null) { return; } Packet packet = e.Packet; AvatarPicksReplyPacket p = (AvatarPicksReplyPacket)packet; Dictionary picks = new Dictionary(); foreach (AvatarPicksReplyPacket.DataBlock b in p.Data) { picks.Add(b.PickID, Utils.BytesToString(b.PickName)); } OnAvatarPicksReply(new AvatarPicksReplyEventArgs(p.AgentData.TargetID, picks)); } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void PickInfoReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_PickInfoReply != null) { Packet packet = e.Packet; PickInfoReplyPacket p = (PickInfoReplyPacket)packet; ProfilePick ret = new ProfilePick(); ret.CreatorID = p.Data.CreatorID; ret.Desc = Utils.BytesToString(p.Data.Desc); ret.Enabled = p.Data.Enabled; ret.Name = Utils.BytesToString(p.Data.Name); ret.OriginalName = Utils.BytesToString(p.Data.OriginalName); ret.ParcelID = p.Data.ParcelID; ret.PickID = p.Data.PickID; ret.PosGlobal = p.Data.PosGlobal; ret.SimName = Utils.BytesToString(p.Data.SimName); ret.SnapshotID = p.Data.SnapshotID; ret.SortOrder = p.Data.SortOrder; ret.TopPick = p.Data.TopPick; ret.User = Utils.BytesToString(p.Data.User); OnPickInfoReply(new PickInfoReplyEventArgs(ret.PickID, ret)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void AvatarClassifiedReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarClassifiedReply != null) { Packet packet = e.Packet; AvatarClassifiedReplyPacket p = (AvatarClassifiedReplyPacket)packet; Dictionary classifieds = new Dictionary(); foreach (AvatarClassifiedReplyPacket.DataBlock b in p.Data) { classifieds.Add(b.ClassifiedID, Utils.BytesToString(b.Name)); } OnAvatarClassifiedReply(new AvatarClassifiedReplyEventArgs(p.AgentData.TargetID, classifieds)); } } /// Process an incoming packet and raise the appropriate events /// The sender /// The EventArgs object containing the packet data protected void ClassifiedInfoReplyHandler(object sender, PacketReceivedEventArgs e) { if (m_AvatarClassifiedReply != null) { Packet packet = e.Packet; ClassifiedInfoReplyPacket p = (ClassifiedInfoReplyPacket)packet; ClassifiedAd ret = new ClassifiedAd(); ret.Desc = Utils.BytesToString(p.Data.Desc); ret.Name = Utils.BytesToString(p.Data.Name); ret.ParcelID = p.Data.ParcelID; ret.ClassifiedID = p.Data.ClassifiedID; ret.Position = p.Data.PosGlobal; ret.SnapShotID = p.Data.SnapshotID; ret.Price = p.Data.PriceForListing; ret.ParentEstate = p.Data.ParentEstate; ret.ClassifiedFlags = p.Data.ClassifiedFlags; ret.Catagory = p.Data.Category; OnClassifiedInfoReply(new ClassifiedInfoReplyEventArgs(ret.ClassifiedID, ret)); } } #endregion Packet Handlers } #region EventArgs /// Provides data for the event /// The event occurs when the simulator sends /// the animation playlist for an agent /// /// The following code example uses the and /// properties to display the animation playlist of an avatar on the window. /// /// // subscribe to the event /// Client.Avatars.AvatarAnimation += Avatars_AvatarAnimation; /// /// private void Avatars_AvatarAnimation(object sender, AvatarAnimationEventArgs e) /// { /// // create a dictionary of "known" animations from the Animations class using System.Reflection /// Dictionary<UUID, string> systemAnimations = new Dictionary<UUID, string>(); /// Type type = typeof(Animations); /// System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); /// foreach (System.Reflection.FieldInfo field in fields) /// { /// systemAnimations.Add((UUID)field.GetValue(type), field.Name); /// } /// /// // find out which animations being played are known animations and which are assets /// foreach (Animation animation in e.Animations) /// { /// if (systemAnimations.ContainsKey(animation.AnimationID)) /// { /// Console.WriteLine("{0} is playing {1} ({2}) sequence {3}", e.AvatarID, /// systemAnimations[animation.AnimationID], animation.AnimationSequence); /// } /// else /// { /// Console.WriteLine("{0} is playing {1} (Asset) sequence {2}", e.AvatarID, /// animation.AnimationID, animation.AnimationSequence); /// } /// } /// } /// /// public class AvatarAnimationEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly List m_Animations; /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } /// Get the list of animations to start public List Animations { get { return m_Animations; } } /// /// Construct a new instance of the AvatarAnimationEventArgs class /// /// The ID of the agent /// The list of animations to start public AvatarAnimationEventArgs(UUID avatarID, List anims) { this.m_AvatarID = avatarID; this.m_Animations = anims; } } /// Provides data for the event /// The event occurs when the simulator sends /// the appearance data for an avatar /// /// The following code example uses the and /// properties to display the selected shape of an avatar on the window. /// /// // subscribe to the event /// Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; /// /// // handle the data when the event is raised /// void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) /// { /// Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") /// } /// /// public class AvatarAppearanceEventArgs : EventArgs { private readonly Simulator m_Simulator; private readonly UUID m_AvatarID; private readonly bool m_IsTrial; private readonly Primitive.TextureEntryFace m_DefaultTexture; private readonly Primitive.TextureEntryFace[] m_FaceTextures; private readonly List m_VisualParams; private readonly byte m_AppearanceVersion; private readonly int m_COFVersion; private readonly AppearanceFlags m_AppearanceFlags; /// Get the Simulator this request is from of the agent public Simulator Simulator { get { return m_Simulator; } } /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } /// true if the agent is a trial account public bool IsTrial { get { return m_IsTrial; } } /// Get the default agent texture public Primitive.TextureEntryFace DefaultTexture { get { return m_DefaultTexture; } } /// Get the agents appearance layer textures public Primitive.TextureEntryFace[] FaceTextures { get { return m_FaceTextures; } } /// Get the for the agent public List VisualParams { get { return m_VisualParams; } } /// Version of the appearance system used. /// Value greater than 0 indicates that server side baking is used public byte AppearanceVersion { get { return m_AppearanceVersion; } } /// Version of the Current Outfit Folder the appearance is based on public int COFVersion { get { return m_COFVersion; } } /// Appearance flags, introduced with server side baking, currently unused public AppearanceFlags AppearanceFlags { get { return m_AppearanceFlags; } } /// /// Construct a new instance of the AvatarAppearanceEventArgs class /// /// The simulator request was from /// The ID of the agent /// true of the agent is a trial account /// The default agent texture /// The agents appearance layer textures /// The for the agent public AvatarAppearanceEventArgs(Simulator sim, UUID avatarID, bool isTrial, Primitive.TextureEntryFace defaultTexture, Primitive.TextureEntryFace[] faceTextures, List visualParams, byte appearanceVersion, int COFVersion, AppearanceFlags appearanceFlags) { this.m_Simulator = sim; this.m_AvatarID = avatarID; this.m_IsTrial = isTrial; this.m_DefaultTexture = defaultTexture; this.m_FaceTextures = faceTextures; this.m_VisualParams = visualParams; this.m_AppearanceVersion = appearanceVersion; this.m_COFVersion = COFVersion; this.m_AppearanceFlags = appearanceFlags; } } /// Represents the interests from the profile of an agent public class AvatarInterestsReplyEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly Avatar.Interests m_Interests; /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } public Avatar.Interests Interests { get { return m_Interests; } } public AvatarInterestsReplyEventArgs(UUID avatarID, Avatar.Interests interests) { this.m_AvatarID = avatarID; this.m_Interests = interests; } } /// The properties of an agent public class AvatarPropertiesReplyEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly Avatar.AvatarProperties m_Properties; /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } public Avatar.AvatarProperties Properties { get { return m_Properties; } } public AvatarPropertiesReplyEventArgs(UUID avatarID, Avatar.AvatarProperties properties) { this.m_AvatarID = avatarID; this.m_Properties = properties; } } public class AvatarGroupsReplyEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly List m_Groups; /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } public List Groups { get { return m_Groups; } } public AvatarGroupsReplyEventArgs(UUID avatarID, List avatarGroups) { this.m_AvatarID = avatarID; this.m_Groups = avatarGroups; } } public class AvatarPicksReplyEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly Dictionary m_Picks; /// Get the ID of the agent public UUID AvatarID { get { return m_AvatarID; } } public Dictionary Picks { get { return m_Picks; } } public AvatarPicksReplyEventArgs(UUID avatarid, Dictionary picks) { this.m_AvatarID = avatarid; this.m_Picks = picks; } } public class PickInfoReplyEventArgs : EventArgs { private readonly UUID m_PickID; private readonly ProfilePick m_Pick; public UUID PickID { get { return m_PickID; } } public ProfilePick Pick { get { return m_Pick; } } public PickInfoReplyEventArgs(UUID pickid, ProfilePick pick) { this.m_PickID = pickid; this.m_Pick = pick; } } public class AvatarClassifiedReplyEventArgs : EventArgs { private readonly UUID m_AvatarID; private readonly Dictionary m_Classifieds; /// Get the ID of the avatar public UUID AvatarID { get { return m_AvatarID; } } public Dictionary Classifieds { get { return m_Classifieds; } } public AvatarClassifiedReplyEventArgs(UUID avatarid, Dictionary classifieds) { this.m_AvatarID = avatarid; this.m_Classifieds = classifieds; } } public class ClassifiedInfoReplyEventArgs : EventArgs { private readonly UUID m_ClassifiedID; private readonly ClassifiedAd m_Classified; public UUID ClassifiedID { get { return m_ClassifiedID; } } public ClassifiedAd Classified { get { return m_Classified; } } public ClassifiedInfoReplyEventArgs(UUID classifiedID, ClassifiedAd Classified) { this.m_ClassifiedID = classifiedID; this.m_Classified = Classified; } } public class UUIDNameReplyEventArgs : EventArgs { private readonly Dictionary m_Names; public Dictionary Names { get { return m_Names; } } public UUIDNameReplyEventArgs(Dictionary names) { this.m_Names = names; } } public class AvatarPickerReplyEventArgs : EventArgs { private readonly UUID m_QueryID; private readonly Dictionary m_Avatars; public UUID QueryID { get { return m_QueryID; } } public Dictionary Avatars { get { return m_Avatars; } } public AvatarPickerReplyEventArgs(UUID queryID, Dictionary avatars) { this.m_QueryID = queryID; this.m_Avatars = avatars; } } public class ViewerEffectEventArgs : EventArgs { private readonly EffectType m_Type; private readonly UUID m_SourceID; private readonly UUID m_TargetID; private readonly Vector3d m_TargetPosition; private readonly float m_Duration; private readonly UUID m_EffectID; public EffectType Type { get { return m_Type; } } public UUID SourceID { get { return m_SourceID; } } public UUID TargetID { get { return m_TargetID; } } public Vector3d TargetPosition { get { return m_TargetPosition; } } public float Duration { get { return m_Duration; } } public UUID EffectID { get { return m_EffectID; } } public ViewerEffectEventArgs(EffectType type, UUID sourceID, UUID targetID, Vector3d targetPos, float duration, UUID id) { this.m_Type = type; this.m_SourceID = sourceID; this.m_TargetID = targetID; this.m_TargetPosition = targetPos; this.m_Duration = duration; this.m_EffectID = id; } } public class ViewerEffectPointAtEventArgs : EventArgs { private readonly Simulator m_Simulator; private readonly UUID m_SourceID; private readonly UUID m_TargetID; private readonly Vector3d m_TargetPosition; private readonly PointAtType m_PointType; private readonly float m_Duration; private readonly UUID m_EffectID; public Simulator Simulator { get { return m_Simulator; } } public UUID SourceID { get { return m_SourceID; } } public UUID TargetID { get { return m_TargetID; } } public Vector3d TargetPosition { get { return m_TargetPosition; } } public PointAtType PointType { get { return m_PointType; } } public float Duration { get { return m_Duration; } } public UUID EffectID { get { return m_EffectID; } } public ViewerEffectPointAtEventArgs(Simulator simulator, UUID sourceID, UUID targetID, Vector3d targetPos, PointAtType pointType, float duration, UUID id) { this.m_Simulator = simulator; this.m_SourceID = sourceID; this.m_TargetID = targetID; this.m_TargetPosition = targetPos; this.m_PointType = pointType; this.m_Duration = duration; this.m_EffectID = id; } } public class ViewerEffectLookAtEventArgs : EventArgs { private readonly UUID m_SourceID; private readonly UUID m_TargetID; private readonly Vector3d m_TargetPosition; private readonly LookAtType m_LookType; private readonly float m_Duration; private readonly UUID m_EffectID; public UUID SourceID { get { return m_SourceID; } } public UUID TargetID { get { return m_TargetID; } } public Vector3d TargetPosition { get { return m_TargetPosition; } } public LookAtType LookType { get { return m_LookType; } } public float Duration { get { return m_Duration; } } public UUID EffectID { get { return m_EffectID; } } public ViewerEffectLookAtEventArgs(UUID sourceID, UUID targetID, Vector3d targetPos, LookAtType lookType, float duration, UUID id) { this.m_SourceID = sourceID; this.m_TargetID = targetID; this.m_TargetPosition = targetPos; this.m_LookType = lookType; this.m_Duration = duration; this.m_EffectID = id; } } /// /// Event args class for display name notification messages /// public class DisplayNameUpdateEventArgs : EventArgs { private string oldDisplayName; private AgentDisplayName displayName; public string OldDisplayName { get { return oldDisplayName; } } public AgentDisplayName DisplayName { get { return displayName; } } public DisplayNameUpdateEventArgs(string oldDisplayName, AgentDisplayName displayName) { this.oldDisplayName = oldDisplayName; this.displayName = displayName; } } #endregion }