/*
* 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
}