Package com.ngt.jopenmetaverse.shared.sim

Source Code of com.ngt.jopenmetaverse.shared.sim.AvatarManager

/**
* A library to interact with Virtual Worlds such as OpenSim
* Copyright (C) 2012  Jitendra Chauhan, Email: jitendra.chauhan@gmail.com
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.ngt.jopenmetaverse.shared.sim;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Map.Entry;

import com.ngt.jopenmetaverse.shared.cap.http.CapsHttpClient;
import com.ngt.jopenmetaverse.shared.cap.http.CapsHttpRequestCompletedArg;
import com.ngt.jopenmetaverse.shared.protocol.AvatarAnimationPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarAppearancePacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarClassifiedReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarGroupsReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarInterestsReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarPickerReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarPickerRequestPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarPicksReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarPropertiesReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.AvatarPropertiesRequestPacket;
import com.ngt.jopenmetaverse.shared.protocol.ClassifiedInfoReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.GenericMessagePacket;
import com.ngt.jopenmetaverse.shared.protocol.Helpers;
import com.ngt.jopenmetaverse.shared.protocol.Packet;
import com.ngt.jopenmetaverse.shared.protocol.PacketType;
import com.ngt.jopenmetaverse.shared.protocol.PickInfoReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.TrackAgentPacket;
import com.ngt.jopenmetaverse.shared.protocol.UUIDNameReplyPacket;
import com.ngt.jopenmetaverse.shared.protocol.UUIDNameRequestPacket;
import com.ngt.jopenmetaverse.shared.protocol.ViewerEffectPacket;
import com.ngt.jopenmetaverse.shared.protocol.primitives.TextureEntry;
import com.ngt.jopenmetaverse.shared.protocol.primitives.TextureEntryFace;
import com.ngt.jopenmetaverse.shared.structureddata.OSD;
import com.ngt.jopenmetaverse.shared.structureddata.OSDMap;
import com.ngt.jopenmetaverse.shared.types.Action;
import com.ngt.jopenmetaverse.shared.types.UUID;
import com.ngt.jopenmetaverse.shared.types.Vector3d;
import com.ngt.jopenmetaverse.shared.util.JLogger;
import com.ngt.jopenmetaverse.shared.util.Utils;
import com.ngt.jopenmetaverse.shared.sim.AgentManager.EffectType;
import com.ngt.jopenmetaverse.shared.sim.AgentManager.LookAtType;
import com.ngt.jopenmetaverse.shared.sim.AgentManager.PointAtType;
import com.ngt.jopenmetaverse.shared.sim.Avatar.ProfileFlags;
import com.ngt.jopenmetaverse.shared.sim.GroupManager.GroupPowers;
import com.ngt.jopenmetaverse.shared.sim.events.CapsEventObservableArg;
import com.ngt.jopenmetaverse.shared.sim.events.EventObservable;
import com.ngt.jopenmetaverse.shared.sim.events.EventObserver;
import com.ngt.jopenmetaverse.shared.sim.events.PacketReceivedEventArgs;
import com.ngt.jopenmetaverse.shared.sim.events.avm.*;
import com.ngt.jopenmetaverse.shared.sim.interfaces.IMessage;
import com.ngt.jopenmetaverse.shared.sim.message.LindenMessages.AgentGroupDataUpdateMessage;
import com.ngt.jopenmetaverse.shared.sim.message.LindenMessages.DisplayNameUpdateMessage;
import com.ngt.jopenmetaverse.shared.sim.message.LindenMessages.GetDisplayNamesMessage;

///// <summary>
///// Retrieve friend status notifications, and retrieve avatar names and
///// profiles
///// </summary>
public class AvatarManager {
    //region Structs
    /// <summary> Information about agents display name </summary>
    public static class AgentDisplayName
    {
        /// <summary> Agent UUID </summary>
        public UUID ID;
        /// <summary> Username </summary>
        public String UserName;
        /// <summary> Display name </summary>
        public String DisplayName;
        /// <summary> First name (legacy) </summary>
        public String LegacyFirstName;
        /// <summary> Last name (legacy) </summary>
        public String LegacyLastName;
        /// <summary> Full name (legacy) </summary>
        public String getLegacyFullName() { return String.format("%s %s", LegacyFirstName, LegacyLastName); }
        /// <summary> Is display name default display name </summary>
        public boolean IsDefaultDisplayName;
        /// <summary> Cache display name until </summary>
        public Date NextUpdate;

        /// <summary>
        /// Creates AgentDisplayName object from OSD
        /// </summary>
        /// <param name="data">Incoming OSD data</param>
        /// <returns>AgentDisplayName object</returns>
        public static AgentDisplayName FromOSD(OSD data)
        {
            AgentDisplayName ret = new AgentDisplayName();

            OSDMap map = (OSDMap)data;
            ret.ID = map.get("id").asUUID();
            ret.UserName = map.get("username").asString();
            ret.DisplayName = map.get("display_name").asString();
            ret.LegacyFirstName = map.get("legacy_first_name").asString();
            ret.LegacyLastName = map.get("legacy_last_name").asString();
            ret.IsDefaultDisplayName = map.get("is_display_name_default").asBoolean();
            ret.NextUpdate = map.get("display_name_next_update").asDate();

            return ret;
        }

        /// <summary>
        /// Return object as OSD map
        /// </summary>
        /// <returns>OSD containing agent's display name data</returns>
        public OSD GetOSD()
        {
            OSDMap map = new OSDMap();
           
            map.put("id", OSD.FromUUID(ID));
            map.put("username",  OSD.FromString(UserName));
            map.put("display_name", OSD.FromString(DisplayName));
            map.put("legacy_first_name",  OSD.FromString(LegacyFirstName));
            map.put("legacy_last_name", OSD.FromString(LegacyLastName));
            map.put("is_display_name_default", OSD.FromBoolean(IsDefaultDisplayName));
            map.put("display_name_next_update", OSD.FromDate(NextUpdate));
           
            return map;
        }

        @Override
        public String toString()
        {
            try {
        return Helpers.StructToString(this);
      } catch (Exception e){
        JLogger.warn(Utils.getExceptionStackTraceAsString(e));
        return e.getMessage();
      }
            //StringBuilder result = new StringBuilder();
            //result.AppendLine();
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "ID", ID, "UUID");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "UserName", UserName, "string");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "DisplayName", DisplayName, "string");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "LegacyFirstName", LegacyFirstName, "string");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "LegaacyLastName", LegaacyLastName, "string");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]" + Environment.NewLine, "IsDefaultDisplayName", IsDefaultDisplayName, "bool");
            //result.AppendFormat("{0, 30}: {1,-40} [{2}]", "NextUpdate", NextUpdate, "DateTime");
            //return result.ToString();
        }
    }

    /// <summary>
    /// Holds group information for Avatars such as those you might find in a profile
    /// </summary>
    public class AvatarGroup
    {
        /// <summary>true of Avatar accepts group notices</summary>
        public boolean AcceptNotices;
        /// <summary>Groups Key</summary>
        public UUID GroupID;
        /// <summary>Texture Key for groups insignia</summary>
        public UUID GroupInsigniaID;
        /// <summary>Name of the group</summary>
        public String GroupName;
        /// <summary>Powers avatar has in the group</summary>
        public EnumSet<com.ngt.jopenmetaverse.shared.sim.GroupManager.GroupPowers> GroupPowers;
        /// <summary>Avatars Currently selected title</summary>
        public String GroupTitle;
        /// <summary>true of Avatar has chosen to list this in their profile</summary>
        public boolean ListInProfile;
    }

    /// <summary>
    /// Contains an animation currently being played by an agent
    /// </summary>
    public class Animation
    {
        /// <summary>The ID of the animation asset</summary>
        public UUID AnimationID;
        /// <summary>A number to indicate start order of currently playing animations</summary>
        /// <remarks>On Linden Grids this number is unique per region, with OpenSim it is per client</remarks>
        public int AnimationSequence;
        /// <summary></summary>
        public UUID AnimationSourceObjectID;
    }

    /// <summary>
    /// Holds group information on an individual profile pick
    /// </summary>
    public class ProfilePick
    {
        public UUID PickID;
        public UUID CreatorID;
        public boolean 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 boolean Enabled;
    }

    public class ClassifiedAd
    {
        public UUID ClassifiedID;
        //uint
        public long Catagory;
        public UUID ParcelID;
        //uint
        public long ParentEstate;
        public UUID SnapShotID;
        public Vector3d Position;
        public byte ClassifiedFlags;
        public int Price;
        public String Name;
        public String Desc;
    }
    //endregion

    public final int MAX_UUIDS_PER_PACKET = 100;

    //region Events

    private EventObservable<AvatarAnimationEventArgs> onAvatarAnimation = new EventObservable<AvatarAnimationEventArgs>();
    public void registerOnAvatarAnimation(EventObserver<AvatarAnimationEventArgs> o)
    {
      onAvatarAnimation.addObserver(o);
    }
    public void unregisterOnAvatarAnimation(EventObserver<AvatarAnimationEventArgs> o)
    {
      onAvatarAnimation.deleteObserver(o);
    }

    private EventObservable<AvatarAppearanceEventArgs> onAvatarAppearance = new EventObservable<AvatarAppearanceEventArgs>();
    public void registerOnAvatarAppearance(EventObserver<AvatarAppearanceEventArgs> o)
    {
      onAvatarAppearance.addObserver(o);
    }
    public void unregisterOnAvatarAppearance(EventObserver<AvatarAppearanceEventArgs> o)
    {
      onAvatarAppearance.deleteObserver(o);
    }
    private EventObservable<UUIDNameReplyEventArgs> onUUIDNameReply = new EventObservable<UUIDNameReplyEventArgs>();
    public void registerOnUUIDNameReply(EventObserver<UUIDNameReplyEventArgs> o)
    {
      onUUIDNameReply.addObserver(o);
    }
    public void unregisterOnUUIDNameReply(EventObserver<UUIDNameReplyEventArgs> o)
    {
      onUUIDNameReply.deleteObserver(o);
    }
    private EventObservable<AvatarInterestsReplyEventArgs> onAvatarInterestsReply = new EventObservable<AvatarInterestsReplyEventArgs>();
    public void registerOnAvatarInterestsReply(EventObserver<AvatarInterestsReplyEventArgs> o)
    {
      onAvatarInterestsReply.addObserver(o);
    }
    public void unregisterOnAvatarInterestsReply(EventObserver<AvatarInterestsReplyEventArgs> o)
    {
      onAvatarInterestsReply.deleteObserver(o);
    }
    private EventObservable<AvatarPropertiesReplyEventArgs> onAvatarPropertiesReply = new EventObservable<AvatarPropertiesReplyEventArgs>();
    public void registerOnAvatarPropertiesReply(EventObserver<AvatarPropertiesReplyEventArgs> o)
    {
      onAvatarPropertiesReply.addObserver(o);
    }
    public void unregisterOnAvatarPropertiesReply(EventObserver<AvatarPropertiesReplyEventArgs> o)
    {
      onAvatarPropertiesReply.deleteObserver(o);
    }
    private EventObservable<AvatarGroupsReplyEventArgs> onAvatarGroupsReply = new EventObservable<AvatarGroupsReplyEventArgs>();
    public void registerOnAvatarGroupsReply(EventObserver<AvatarGroupsReplyEventArgs> o)
    {
      onAvatarGroupsReply.addObserver(o);
    }
    public void unregisterOnAvatarGroupsReply(EventObserver<AvatarGroupsReplyEventArgs> o)
    {
      onAvatarGroupsReply.deleteObserver(o);
    }
    private EventObservable<AvatarPickerReplyEventArgs> onAvatarPickerReply = new EventObservable<AvatarPickerReplyEventArgs>();
    public void registerOnAvatarPickerReply(EventObserver<AvatarPickerReplyEventArgs> o)
    {
      onAvatarPickerReply.addObserver(o);
    }
    public void unregisterOnAvatarPickerReply(EventObserver<AvatarPickerReplyEventArgs> o)
    {
      onAvatarPickerReply.deleteObserver(o);
    }
    private EventObservable<ViewerEffectPointAtEventArgs> onViewerEffectPointAt = new EventObservable<ViewerEffectPointAtEventArgs>();
    public void registerOnViewerEffectPointAt(EventObserver<ViewerEffectPointAtEventArgs> o)
    {
      onViewerEffectPointAt.addObserver(o);
    }
    public void unregisterOnViewerEffectPointAt(EventObserver<ViewerEffectPointAtEventArgs> o)
    {
      onViewerEffectPointAt.deleteObserver(o);
    }
    private EventObservable<ViewerEffectLookAtEventArgs> onViewerEffectLookAt = new EventObservable<ViewerEffectLookAtEventArgs>();
    public void registerOnViewerEffectLookAt(EventObserver<ViewerEffectLookAtEventArgs> o)
    {
      onViewerEffectLookAt.addObserver(o);
    }
    public void unregisterOnViewerEffectLookAt(EventObserver<ViewerEffectLookAtEventArgs> o)
    {
      onViewerEffectLookAt.deleteObserver(o);
    }
    private EventObservable<ViewerEffectEventArgs> onViewerEffect = new EventObservable<ViewerEffectEventArgs>();
    public void registerOnViewerEffect(EventObserver<ViewerEffectEventArgs> o)
    {
      onViewerEffect.addObserver(o);
    }
    public void unregisterOnViewerEffect(EventObserver<ViewerEffectEventArgs> o)
    {
      onViewerEffect.deleteObserver(o);
    }
    private EventObservable<AvatarPicksReplyEventArgs> onAvatarPicksReply = new EventObservable<AvatarPicksReplyEventArgs>();
    public void registerOnAvatarPicksReply(EventObserver<AvatarPicksReplyEventArgs> o)
    {
      onAvatarPicksReply.addObserver(o);
    }
    public void unregisterOnAvatarPicksReply(EventObserver<AvatarPicksReplyEventArgs> o)
    {
      onAvatarPicksReply.deleteObserver(o);
    }
    private EventObservable<PickInfoReplyEventArgs> onPickInfoReply = new EventObservable<PickInfoReplyEventArgs>();
    public void registerOnPickInfoReply(EventObserver<PickInfoReplyEventArgs> o)
    {
      onPickInfoReply.addObserver(o);
    }
    public void unregisterOnPickInfoReply(EventObserver<PickInfoReplyEventArgs> o)
    {
      onPickInfoReply.deleteObserver(o);
    }
    private EventObservable<AvatarClassifiedReplyEventArgs> onAvatarClassifiedReply = new EventObservable<AvatarClassifiedReplyEventArgs>();
    public void registerOnAvatarClassifiedReply(EventObserver<AvatarClassifiedReplyEventArgs> o)
    {
      onAvatarClassifiedReply.addObserver(o);
    }
    public void unregisterOnAvatarClassifiedReply(EventObserver<AvatarClassifiedReplyEventArgs> o)
    {
      onAvatarClassifiedReply.deleteObserver(o);
    }
    private EventObservable<ClassifiedInfoReplyEventArgs> onClassifiedInfoReply = new EventObservable<ClassifiedInfoReplyEventArgs>();
    public void registerOnClassifiedInfoReply(EventObserver<ClassifiedInfoReplyEventArgs> o)
    {
      onClassifiedInfoReply.addObserver(o);
    }
    public void unregisterOnClassifiedInfoReply(EventObserver<ClassifiedInfoReplyEventArgs> o)
    {
      onClassifiedInfoReply.deleteObserver(o);
    }
    private EventObservable<DisplayNameUpdateEventArgs> onDisplayNameUpdate = new EventObservable<DisplayNameUpdateEventArgs>();
    public void registerOnDisplayNameUpdate(EventObserver<DisplayNameUpdateEventArgs> o)
    {
      onDisplayNameUpdate.addObserver(o);
    }
    public void unregisterOnDisplayNameUpdate(EventObserver<DisplayNameUpdateEventArgs> o)
    {
      onDisplayNameUpdate.deleteObserver(o);
    }
       
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarAnimationEventArgs> m_AvatarAnimation;
//
//        ///<summary>Raises the AvatarAnimation Event</summary>
//        /// <param name="e">An AvatarAnimationEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarAnimation(AvatarAnimationEventArgs e)
//        {
//            EventHandler<AvatarAnimationEventArgs> handler = m_AvatarAnimation;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarAnimationLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// an agents animation playlist</summary>
//        public event EventHandler<AvatarAnimationEventArgs> AvatarAnimation
//        {
//            add { lock (m_AvatarAnimationLock) { m_AvatarAnimation += value; } }
//            remove { lock (m_AvatarAnimationLock) { m_AvatarAnimation -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarAppearanceEventArgs> m_AvatarAppearance;
//
//        ///<summary>Raises the AvatarAppearance Event</summary>
//        /// <param name="e">A AvatarAppearanceEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarAppearance(AvatarAppearanceEventArgs e)
//        {
//            EventHandler<AvatarAppearanceEventArgs> handler = m_AvatarAppearance;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarAppearanceLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the appearance information for an agent</summary>
//        public event EventHandler<AvatarAppearanceEventArgs> AvatarAppearance
//        {
//            add { lock (m_AvatarAppearanceLock) { m_AvatarAppearance += value; } }
//            remove { lock (m_AvatarAppearanceLock) { m_AvatarAppearance -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<UUIDNameReplyEventArgs> m_UUIDNameReply;
//
//        ///<summary>Raises the UUIDNameReply Event</summary>
//        /// <param name="e">A UUIDNameReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnUUIDNameReply(UUIDNameReplyEventArgs e)
//        {
//            EventHandler<UUIDNameReplyEventArgs> handler = m_UUIDNameReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_UUIDNameReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// agent names/id values</summary>
//        public event EventHandler<UUIDNameReplyEventArgs> UUIDNameReply
//        {
//            add { lock (m_UUIDNameReplyLock) { m_UUIDNameReply += value; } }
//            remove { lock (m_UUIDNameReplyLock) { m_UUIDNameReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarInterestsReplyEventArgs> m_AvatarInterestsReply;
//
//        ///<summary>Raises the AvatarInterestsReply Event</summary>
//        /// <param name="e">A AvatarInterestsReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarInterestsReply(AvatarInterestsReplyEventArgs e)
//        {
//            EventHandler<AvatarInterestsReplyEventArgs> handler = m_AvatarInterestsReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarInterestsReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the interests listed in an agents profile</summary>
//        public event EventHandler<AvatarInterestsReplyEventArgs> AvatarInterestsReply
//        {
//            add { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply += value; } }
//            remove { lock (m_AvatarInterestsReplyLock) { m_AvatarInterestsReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarPropertiesReplyEventArgs> m_AvatarPropertiesReply;
//
//        ///<summary>Raises the AvatarPropertiesReply Event</summary>
//        /// <param name="e">A AvatarPropertiesReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarPropertiesReply(AvatarPropertiesReplyEventArgs e)
//        {
//            EventHandler<AvatarPropertiesReplyEventArgs> handler = m_AvatarPropertiesReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarPropertiesReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// profile property information for an agent</summary>
//        public event EventHandler<AvatarPropertiesReplyEventArgs> AvatarPropertiesReply
//        {
//            add { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply += value; } }
//            remove { lock (m_AvatarPropertiesReplyLock) { m_AvatarPropertiesReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarGroupsReplyEventArgs> m_AvatarGroupsReply;
//
//        ///<summary>Raises the AvatarGroupsReply Event</summary>
//        /// <param name="e">A AvatarGroupsReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarGroupsReply(AvatarGroupsReplyEventArgs e)
//        {
//            EventHandler<AvatarGroupsReplyEventArgs> handler = m_AvatarGroupsReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarGroupsReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the group membership an agent is a member of</summary>
//        public event EventHandler<AvatarGroupsReplyEventArgs> AvatarGroupsReply
//        {
//            add { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply += value; } }
//            remove { lock (m_AvatarGroupsReplyLock) { m_AvatarGroupsReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarPickerReplyEventArgs> m_AvatarPickerReply;
//
//        ///<summary>Raises the AvatarPickerReply Event</summary>
//        /// <param name="e">A AvatarPickerReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarPickerReply(AvatarPickerReplyEventArgs e)
//        {
//            EventHandler<AvatarPickerReplyEventArgs> handler = m_AvatarPickerReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarPickerReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// name/id pair</summary>
//        public event EventHandler<AvatarPickerReplyEventArgs> AvatarPickerReply
//        {
//            add { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply += value; } }
//            remove { lock (m_AvatarPickerReplyLock) { m_AvatarPickerReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<ViewerEffectPointAtEventArgs> m_ViewerEffectPointAt;
//
//        ///<summary>Raises the ViewerEffectPointAt Event</summary>
//        /// <param name="e">A ViewerEffectPointAtEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnViewerEffectPointAt(ViewerEffectPointAtEventArgs e)
//        {
//            EventHandler<ViewerEffectPointAtEventArgs> handler = m_ViewerEffectPointAt;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_ViewerEffectPointAtLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the objects and effect when an agent is pointing at</summary>
//        public event EventHandler<ViewerEffectPointAtEventArgs> ViewerEffectPointAt
//        {
//            add { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt += value; } }
//            remove { lock (m_ViewerEffectPointAtLock) { m_ViewerEffectPointAt -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<ViewerEffectLookAtEventArgs> m_ViewerEffectLookAt;
//
//        ///<summary>Raises the ViewerEffectLookAt Event</summary>
//        /// <param name="e">A ViewerEffectLookAtEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnViewerEffectLookAt(ViewerEffectLookAtEventArgs e)
//        {
//            EventHandler<ViewerEffectLookAtEventArgs> handler = m_ViewerEffectLookAt;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_ViewerEffectLookAtLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the objects and effect when an agent is looking at</summary>
//        public event EventHandler<ViewerEffectLookAtEventArgs> ViewerEffectLookAt
//        {
//            add { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt += value; } }
//            remove { lock (m_ViewerEffectLookAtLock) { m_ViewerEffectLookAt -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<ViewerEffectEventArgs> m_ViewerEffect;
//
//        ///<summary>Raises the ViewerEffect Event</summary>
//        /// <param name="e">A ViewerEffectEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnViewerEffect(ViewerEffectEventArgs e)
//        {
//            EventHandler<ViewerEffectEventArgs> handler = m_ViewerEffect;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_ViewerEffectLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// an agents viewer effect information</summary>
//        public event EventHandler<ViewerEffectEventArgs> ViewerEffect
//        {
//            add { lock (m_ViewerEffectLock) { m_ViewerEffect += value; } }
//            remove { lock (m_ViewerEffectLock) { m_ViewerEffect -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarPicksReplyEventArgs> m_AvatarPicksReply;
//
//        ///<summary>Raises the AvatarPicksReply Event</summary>
//        /// <param name="e">A AvatarPicksReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarPicksReply(AvatarPicksReplyEventArgs e)
//        {
//            EventHandler<AvatarPicksReplyEventArgs> handler = m_AvatarPicksReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarPicksReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the top picks from an agents profile</summary>
//        public event EventHandler<AvatarPicksReplyEventArgs> AvatarPicksReply
//        {
//            add { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply += value; } }
//            remove { lock (m_AvatarPicksReplyLock) { m_AvatarPicksReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<PickInfoReplyEventArgs> m_PickInfoReply;
//
//        ///<summary>Raises the PickInfoReply Event</summary>
//        /// <param name="e">A PickInfoReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnPickInfoReply(PickInfoReplyEventArgs e)
//        {
//            EventHandler<PickInfoReplyEventArgs> handler = m_PickInfoReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_PickInfoReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the Pick details</summary>
//        public event EventHandler<PickInfoReplyEventArgs> PickInfoReply
//        {
//            add { lock (m_PickInfoReplyLock) { m_PickInfoReply += value; } }
//            remove { lock (m_PickInfoReplyLock) { m_PickInfoReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<AvatarClassifiedReplyEventArgs> m_AvatarClassifiedReply;
//
//        ///<summary>Raises the AvatarClassifiedReply Event</summary>
//        /// <param name="e">A AvatarClassifiedReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnAvatarClassifiedReply(AvatarClassifiedReplyEventArgs e)
//        {
//            EventHandler<AvatarClassifiedReplyEventArgs> handler = m_AvatarClassifiedReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_AvatarClassifiedReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the classified ads an agent has placed</summary>
//        public event EventHandler<AvatarClassifiedReplyEventArgs> AvatarClassifiedReply
//        {
//            add { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply += value; } }
//            remove { lock (m_AvatarClassifiedReplyLock) { m_AvatarClassifiedReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<ClassifiedInfoReplyEventArgs> m_ClassifiedInfoReply;
//
//        ///<summary>Raises the ClassifiedInfoReply Event</summary>
//        /// <param name="e">A ClassifiedInfoReplyEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnClassifiedInfoReply(ClassifiedInfoReplyEventArgs e)
//        {
//            EventHandler<ClassifiedInfoReplyEventArgs> handler = m_ClassifiedInfoReply;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_ClassifiedInfoReplyLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the details of a classified ad</summary>
//        public event EventHandler<ClassifiedInfoReplyEventArgs> ClassifiedInfoReply
//        {
//            add { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply += value; } }
//            remove { lock (m_ClassifiedInfoReplyLock) { m_ClassifiedInfoReply -= value; } }
//        }
//
//        /// <summary>The event subscribers, null of no subscribers</summary>
//        private EventHandler<DisplayNameUpdateEventArgs> m_DisplayNameUpdate;
//
//        ///<summary>Raises the DisplayNameUpdate Event</summary>
//        /// <param name="e">A DisplayNameUpdateEventArgs object containing
//        /// the data sent from the simulator</param>
//        protected virtual void OnDisplayNameUpdate(DisplayNameUpdateEventArgs e)
//        {
//            EventHandler<DisplayNameUpdateEventArgs> handler = m_DisplayNameUpdate;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_DisplayNameUpdateLock = new object();
//
//        /// <summary>Raised when the simulator sends us data containing
//        /// the details of display name change</summary>
//        public event EventHandler<DisplayNameUpdateEventArgs> DisplayNameUpdate
//        {
//            add { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate += value; } }
//            remove { lock (m_DisplayNameUpdateLock) { m_DisplayNameUpdate -= value; } }
//        }
//
        //endregion Events

   
   
        //region Delegates
        /// <summary>
        /// Callback giving results when fetching display names
        /// </summary>
        /// <param name="success">If the request was successful</param>
        /// <param name="names">Array of display names</param>
        /// <param name="badIDs">Array of UUIDs that could not be fetched</param>
    //TODO need to implement
//        public delegate void DisplayNamesCallback(bool success, AgentDisplayName[] names, UUID[] badIDs);
        //endregion Delegates

    private GridClient Client;

    /// <summary>
    /// Represents other avatars
    /// </summary>
    /// <param name="client"></param>
    public AvatarManager(GridClient client)
    {
      Client = client;
      // Avatar appearance callback
      // Client.network.RegisterCallback(PacketType.AvatarAppearance, AvatarAppearanceHandler);

      Client.network.RegisterCallback(PacketType.AvatarAppearance, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarAppearanceHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Avatar profile callbacks
      // Client.network.RegisterCallback(PacketType.AvatarPropertiesReply, AvatarPropertiesHandler);

      Client.network.RegisterCallback(PacketType.AvatarPropertiesReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarPropertiesHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
     
      // // Client.network.RegisterCallback(PacketType.AvatarStatisticsReply, AvatarStatisticsHandler);

//      Client.network.RegisterCallback(PacketType.AvatarStatisticsReply, new EventObserver<PacketReceivedEventArgs>()
//          {
//        @Override
//        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
//          try{ AvatarStatisticsHandler(o, arg);}
//          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
//        }}
//          );
     
      // Client.network.RegisterCallback(PacketType.AvatarInterestsReply, AvatarInterestsHandler);

      Client.network.RegisterCallback(PacketType.AvatarInterestsReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarInterestsHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Avatar group callback
      // Client.network.RegisterCallback(PacketType.AvatarGroupsReply, AvatarGroupsReplyHandler);

      Client.network.RegisterCallback(PacketType.AvatarGroupsReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarGroupsReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterEventCallback("AgentGroupDataUpdate", new Caps.EventQueueCallback(AvatarGroupsReplyMessageHandler);

      Client.network.RegisterEventCallback("AgentGroupDataUpdate", new EventObserver<CapsEventObservableArg>()
          {
        @Override
        public void handleEvent(Observable o,CapsEventObservableArg arg) {
          try{ AvatarGroupsReplyMessageHandler(arg.getCapsKey(), arg.getMessage(), arg.getSimulator());}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterEventCallback("AvatarGroupsReply", new Caps.EventQueueCallback(AvatarGroupsReplyMessageHandler);

      Client.network.RegisterEventCallback("AvatarGroupsReply", new EventObserver<CapsEventObservableArg>()
          {
        @Override
        public void handleEvent(Observable o,CapsEventObservableArg arg) {
          try{ AvatarGroupsReplyMessageHandler(arg.getCapsKey(), arg.getMessage(), arg.getSimulator());}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Viewer effect callback
      // Client.network.RegisterCallback(PacketType.ViewerEffect, ViewerEffectHandler);

      Client.network.RegisterCallback(PacketType.ViewerEffect, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ ViewerEffectHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Other callbacks
      // Client.network.RegisterCallback(PacketType.UUIDNameReply, UUIDNameReplyHandler);

      Client.network.RegisterCallback(PacketType.UUIDNameReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ UUIDNameReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterCallback(PacketType.AvatarPickerReply, AvatarPickerReplyHandler);

      Client.network.RegisterCallback(PacketType.AvatarPickerReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarPickerReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterCallback(PacketType.AvatarAnimation, AvatarAnimationHandler);

      Client.network.RegisterCallback(PacketType.AvatarAnimation, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarAnimationHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Picks callbacks
      // Client.network.RegisterCallback(PacketType.AvatarPicksReply, AvatarPicksReplyHandler);

      Client.network.RegisterCallback(PacketType.AvatarPicksReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarPicksReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterCallback(PacketType.PickInfoReply, PickInfoReplyHandler);

      Client.network.RegisterCallback(PacketType.PickInfoReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ PickInfoReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Classifieds callbacks
      // Client.network.RegisterCallback(PacketType.AvatarClassifiedReply, AvatarClassifiedReplyHandler);

      Client.network.RegisterCallback(PacketType.AvatarClassifiedReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ AvatarClassifiedReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      // Client.network.RegisterCallback(PacketType.ClassifiedInfoReply, ClassifiedInfoReplyHandler);

      Client.network.RegisterCallback(PacketType.ClassifiedInfoReply, new EventObserver<PacketReceivedEventArgs>()
          {
        @Override
        public void handleEvent(Observable o,PacketReceivedEventArgs arg) {
          try{ ClassifiedInfoReplyHandler(o, arg);}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
      //
      // Client.network.RegisterEventCallback("DisplayNameUpdate", new Caps.EventQueueCallback(DisplayNameUpdateMessageHandler);
      Client.network.RegisterEventCallback("DisplayNameUpdate", new EventObserver<CapsEventObservableArg>()
          {
        @Override
        public void handleEvent(Observable o,CapsEventObservableArg arg) {
          try{ DisplayNameUpdateMessageHandler(arg.getCapsKey(), arg.getMessage(), arg.getSimulator());}
          catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
        }}
          );
    }

        /// <summary>Tracks the specified avatar on your map</summary>
        /// <param name="preyID">Avatar ID to track</param>
        public void RequestTrackAgent(UUID preyID)
        {
            TrackAgentPacket p = new TrackAgentPacket();
            p.AgentData.AgentID = Client.self.getAgentID();
            p.AgentData.SessionID = Client.self.getSessionID();
            p.TargetData.PreyID = preyID;
            Client.network.SendPacket(p);
        }

        /// <summary>
        /// Request a single avatar name
        /// </summary>
        /// <param name="id">The avatar key to retrieve a name for</param>
        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);
        }

        /// <summary>
        /// Request a list of avatar names
        /// </summary>
        /// <param name="ids">The avatar keys to retrieve names for</param>
        public void RequestAvatarNames(List<UUID> ids)
        {
            int m = MAX_UUIDS_PER_PACKET;
            int n = ids.size() / 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.get(i);
                }

                Client.network.SendPacket(request);
            }

            // Get any remaining names after left after the full requests
            if (ids.size() > n * m)
            {
                request = new UUIDNameRequestPacket();
                request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.size() - n * m];

                for (; i < ids.size(); i++)
                {
                    request.UUIDNameBlock[i % m] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
                    request.UUIDNameBlock[i % m].ID = ids.get(i);
                }

                Client.network.SendPacket(request);
            }
        }

        /// <summary>
        /// Check if Display Names functionality is available
        /// </summary>
        /// <returns>True if Display name functionality is available</returns>
        public boolean DisplayNamesAvailable()
        {
            return (Client.network.getCurrentSim() != null && Client.network.getCurrentSim().Caps != null) && Client.network.getCurrentSim().Caps.CapabilityURI("GetDisplayNames") != null;
        }

        /// <summary>
        /// Request retrieval of display names (max 90 names per request)
        /// </summary>
        /// <param name="ids">List of UUIDs to lookup</param>
        /// <param name="callback">Callback to report result of the operation</param>
        public void GetDisplayNames(final List<UUID> ids, final EventObserver<DisplayNamesCallbackArgs> callback) throws URISyntaxException
        {
            if (!DisplayNamesAvailable() || ids.size() == 0)
            {
                callback.handleEvent(null, new DisplayNamesCallbackArgs(false, null, null));
            }

            StringBuilder query = new StringBuilder();
            for (int i = 0; i < ids.size() && i < 90; i++)
            {
                query.append(String.format("ids=%s", ids.get(i)));
                if (i < ids.size() - 1)
                {
                    query.append("&");
                }
            }

            URI uri = new URI(Client.network.getCurrentSim().Caps.CapabilityURI("GetDisplayNames").toString() + "/?" + query);

            CapsHttpClient cap = new CapsHttpClient(uri);
           
            cap.addRequestCompleteObserver(new EventObserver<CapsHttpRequestCompletedArg>(){
        @Override
        public void handleEvent(Observable o, CapsHttpRequestCompletedArg arg) {
          // TODO Auto-generated method stub
          CapsHttpClient client = arg.getClient();
          OSD result = arg.getResult();
          Exception error = arg.getError();
           try
                     {
                         if (error != null)
                             throw error;
                         GetDisplayNamesMessage msg = new GetDisplayNamesMessage();
                         msg.Deserialize((OSDMap) result);
                         callback.handleEvent(null, new DisplayNamesCallbackArgs(true, msg.Agents, msg.BadIDs));
                     }
                     catch (Exception ex)
                     {
                         JLogger.warn("Failed to call GetDisplayNames capability: " + Utils.getExceptionStackTraceAsString(ex));
//                         callback(false, null, null);
                         callback.handleEvent(null, new DisplayNamesCallbackArgs(false, null, null));
                     }
        }
            });
//            cap.OnComplete += (CapsHttpClient 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, "", Client.settings.CAPS_TIMEOUT);
        }

        /// <summary>
        /// Start a request for Avatar Properties
        /// </summary>
        /// <param name="avatarid"></param>
        public void RequestAvatarProperties(UUID avatarid)
        {
            AvatarPropertiesRequestPacket aprp = new AvatarPropertiesRequestPacket();

            aprp.AgentData.AgentID = Client.self.getAgentID();
            aprp.AgentData.SessionID = Client.self.getSessionID();
            aprp.AgentData.AvatarID = avatarid;

            Client.network.SendPacket(aprp);
        }

        /// <summary>
        /// Search for an avatar (first name, last name)
        /// </summary>
        /// <param name="name">The name to search for</param>
        /// <param name="queryID">An ID to associate with this query</param>
        public void RequestAvatarNameSearch(String name, UUID queryID)
        {
            AvatarPickerRequestPacket aprp = new AvatarPickerRequestPacket();

            aprp.AgentData.AgentID = Client.self.getAgentID();
            aprp.AgentData.SessionID = Client.self.getSessionID();
            aprp.AgentData.QueryID = queryID;
            aprp.Data.Name = Utils.stringToBytesWithTrailingNullByte(name);

            Client.network.SendPacket(aprp);
        }

        /// <summary>
        /// Start a request for Avatar Picks
        /// </summary>
        /// <param name="avatarid">UUID of the avatar</param>
        public void RequestAvatarPicks(UUID avatarid)
        {
            GenericMessagePacket gmp = new GenericMessagePacket();

            gmp.AgentData.AgentID = Client.self.getAgentID();
            gmp.AgentData.SessionID = Client.self.getSessionID();
            gmp.AgentData.TransactionID = UUID.Zero;

            gmp.MethodData.Method = Utils.stringToBytesWithTrailingNullByte("avatarpicksrequest");
            gmp.MethodData.Invoice = UUID.Zero;
            gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
            gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[0].Parameter = Utils.stringToBytesWithTrailingNullByte(avatarid.toString());

            Client.network.SendPacket(gmp);
        }

        /// <summary>
        /// Start a request for Avatar Classifieds
        /// </summary>
        /// <param name="avatarid">UUID of the avatar</param>
        public void RequestAvatarClassified(UUID avatarid)
        {
            GenericMessagePacket gmp = new GenericMessagePacket();

            gmp.AgentData.AgentID = Client.self.getAgentID();
            gmp.AgentData.SessionID = Client.self.getSessionID();
            gmp.AgentData.TransactionID = UUID.Zero;

            gmp.MethodData.Method = Utils.stringToBytesWithTrailingNullByte("avatarclassifiedsrequest");
            gmp.MethodData.Invoice = UUID.Zero;
            gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
            gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[0].Parameter = Utils.stringToBytesWithTrailingNullByte(avatarid.toString());

            Client.network.SendPacket(gmp);
        }

        /// <summary>
        /// Start a request for details of a specific profile pick
        /// </summary>
        /// <param name="avatarid">UUID of the avatar</param>
        /// <param name="pickid">UUID of the profile pick</param>
        public void RequestPickInfo(UUID avatarid, UUID pickid)
        {
            GenericMessagePacket gmp = new GenericMessagePacket();

            gmp.AgentData.AgentID = Client.self.getAgentID();
            gmp.AgentData.SessionID = Client.self.getSessionID();
            gmp.AgentData.TransactionID = UUID.Zero;

            gmp.MethodData.Method = Utils.stringToBytesWithTrailingNullByte("pickinforequest");
            gmp.MethodData.Invoice = UUID.Zero;
            gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
            gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[0].Parameter = Utils.stringToBytesWithTrailingNullByte(avatarid.toString());
            gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[1].Parameter = Utils.stringToBytesWithTrailingNullByte(pickid.toString());

            Client.network.SendPacket(gmp);
        }

        /// <summary>
        /// Start a request for details of a specific profile classified
        /// </summary>
        /// <param name="avatarid">UUID of the avatar</param>
        /// <param name="classifiedid">UUID of the profile classified</param>
        public void RequestClassifiedInfo(UUID avatarid, UUID classifiedid)
        {
            GenericMessagePacket gmp = new GenericMessagePacket();

            gmp.AgentData.AgentID = Client.self.getAgentID();
            gmp.AgentData.SessionID = Client.self.getSessionID();
            gmp.AgentData.TransactionID = UUID.Zero;

            gmp.MethodData.Method = Utils.stringToBytesWithTrailingNullByte("classifiedinforequest");
            gmp.MethodData.Invoice = UUID.Zero;
            gmp.ParamList = new GenericMessagePacket.ParamListBlock[2];
            gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[0].Parameter = Utils.stringToBytesWithTrailingNullByte(avatarid.toString());
            gmp.ParamList[1] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[1].Parameter = Utils.stringToBytesWithTrailingNullByte(classifiedid.toString());

            Client.network.SendPacket(gmp);
        }

        //region Packet Handlers

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void UUIDNameReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onUUIDNameReply != null)
            {
                Packet packet = e.getPacket();
                Map<UUID, String> names = new HashMap<UUID, String>();
                UUIDNameReplyPacket reply = (UUIDNameReplyPacket)packet;

                for (UUIDNameReplyPacket.UUIDNameBlockBlock block : reply.UUIDNameBlock)
                {
                    names.put(block.ID, Utils.bytesWithTrailingNullByteToString(block.FirstName) +
                        " " + Utils.bytesWithTrailingNullByteToString(block.LastName));
                }

                onUUIDNameReply.raiseEvent(new UUIDNameReplyEventArgs(names));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarAnimationHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();

            if (onAvatarAnimation != null)
            {
                AvatarAnimationPacket data = (AvatarAnimationPacket)packet;

                List<Animation> signaledAnimations = new ArrayList<Animation>(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);
                }

                onAvatarAnimation.raiseEvent(new AvatarAnimationEventArgs(data.Sender.ID, signaledAnimations));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarAppearanceHandler(Object sender, PacketReceivedEventArgs e) throws Exception
        {
            if (onAvatarAppearance != null || Client.settings.AVATAR_TRACKING)
            {
                Packet packet = e.getPacket();
                Simulator simulator = e.getSimulator();

                final AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet;

                List<Byte> visualParams = new ArrayList<Byte>();
                for (AvatarAppearancePacket.VisualParamBlock block : appearance.VisualParam)
                {
                    visualParams.add(block.ParamValue);
                }

                TextureEntry textureEntry = new TextureEntry(appearance.ObjectData.TextureEntry, 0,
                        appearance.ObjectData.TextureEntry.length);

                TextureEntryFace defaultTexture = textureEntry.DefaultTexture;
                TextureEntryFace[] faceTextures = textureEntry.FaceTextures;

//              Avatar av = simulator.ObjectsAvatars.Find((Avatar a) => { return a.ID == appearance.Sender.ID; });
                final Avatar[] tmpAvatar = new Avatar[]{null};
                simulator.ObjectsAvatars.foreach(new Action<Entry<Long, Avatar>>(){
          public void execute(Entry<Long, Avatar> e) {
            if(e.getValue().ID.equals(appearance.Sender.ID))
              tmpAvatar[0] = e.getValue();
         
                }
                );
                Avatar av = tmpAvatar[0];
                if (av != null)
                {
                    av.Textures = textureEntry;
                    //TODO need to do better
                    av.VisualParameters = new byte[visualParams.size()];
                    int i = 0;
                    for (Byte byte1 : visualParams)
                    {
                      av.VisualParameters[i] = byte1;
                        i ++;
                    }
                }

                onAvatarAppearance.raiseEvent(new AvatarAppearanceEventArgs(simulator, appearance.Sender.ID, appearance.Sender.IsTrial,
                    defaultTexture, faceTextures, visualParams));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarPropertiesHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarPropertiesReply != null)
            {
                Packet packet = e.getPacket();
                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.bytesWithTrailingNullByteToString(reply.PropertiesData.AboutText);
                properties.FirstLifeText = Utils.bytesWithTrailingNullByteToString(reply.PropertiesData.FLAboutText);
                properties.BornOn = Utils.bytesWithTrailingNullByteToString(reply.PropertiesData.BornOn);
                //properties.CharterMember = Utils.bytesWithTrailingNullByteToString(reply.PropertiesData.CharterMember);
                //uint
                long charter = Utils.bytesToUIntLit(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.bytesWithTrailingNullByteToString(reply.PropertiesData.CharterMember);
                }
                properties.Flags = ProfileFlags.get(reply.PropertiesData.Flags);
                properties.ProfileURL = Utils.bytesWithTrailingNullByteToString(reply.PropertiesData.ProfileURL);

                onAvatarPropertiesReply.raiseEvent(new AvatarPropertiesReplyEventArgs(reply.AgentData.AvatarID, properties));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarInterestsHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarInterestsReply != null)
            {
                Packet packet = e.getPacket();

                AvatarInterestsReplyPacket airp = (AvatarInterestsReplyPacket)packet;
                Avatar.Interests interests = new Avatar.Interests();

                interests.WantToMask = airp.PropertiesData.WantToMask;
                interests.WantToText = Utils.bytesWithTrailingNullByteToString(airp.PropertiesData.WantToText);
                interests.SkillsMask = airp.PropertiesData.SkillsMask;
                interests.SkillsText = Utils.bytesWithTrailingNullByteToString(airp.PropertiesData.SkillsText);
                interests.LanguagesText = Utils.bytesWithTrailingNullByteToString(airp.PropertiesData.LanguagesText);

                onAvatarInterestsReply.raiseEvent(new AvatarInterestsReplyEventArgs(airp.AgentData.AvatarID, interests));
            }
        }

        /// <summary>
        /// EQ Message fired when someone nearby changes their display name
        /// </summary>
        /// <param name="capsKey">The message key</param>
        /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
        /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
        protected void DisplayNameUpdateMessageHandler(String capsKey, IMessage message, Simulator simulator)
        {
            if (onDisplayNameUpdate != null)
            {
                DisplayNameUpdateMessage msg = (DisplayNameUpdateMessage) message;
                onDisplayNameUpdate.raiseEvent(new DisplayNameUpdateEventArgs(msg.OldDisplayName, msg.DisplayName));
            }
        }

        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="capsKey">The message key</param>
        /// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
        /// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
        protected void AvatarGroupsReplyMessageHandler(String capsKey, IMessage message, Simulator simulator)
        {
            AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message;
            List<AvatarGroup> avatarGroups = new ArrayList<AvatarGroup>(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.raiseEvent(new AvatarGroupsReplyEventArgs(msg.AgentID, avatarGroups));
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarGroupsReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarGroupsReply != null)
            {
                Packet packet = e.getPacket();
                AvatarGroupsReplyPacket groups = (AvatarGroupsReplyPacket)packet;
                List<AvatarGroup> avatarGroups = new ArrayList<AvatarGroup>(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.bytesWithTrailingNullByteToString(groups.GroupData[i].GroupName);
                    avatarGroup.GroupPowers = GroupPowers.get(groups.GroupData[i].GroupPowers.longValue());
                    avatarGroup.GroupTitle = Utils.bytesWithTrailingNullByteToString(groups.GroupData[i].GroupTitle);
                    avatarGroup.ListInProfile = groups.NewGroupData.ListInProfile;

                    avatarGroups.add(avatarGroup);
                }

                onAvatarGroupsReply.raiseEvent(new AvatarGroupsReplyEventArgs(groups.AgentData.AvatarID, avatarGroups));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarPickerReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarPickerReply != null)
            {
                Packet packet = e.getPacket();
                AvatarPickerReplyPacket reply = (AvatarPickerReplyPacket)packet;
                Map<UUID, String> avatars = new HashMap<UUID, String>();

                for (AvatarPickerReplyPacket.DataBlock block : reply.Data)
                {
                    avatars.put(block.AvatarID,  Utils.bytesWithTrailingNullByteToString(block.FirstName) +
                        " " + Utils.bytesWithTrailingNullByteToString(block.LastName));
                }
                onAvatarPickerReply.raiseEvent(new AvatarPickerReplyEventArgs(reply.AgentData.QueryID, avatars));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void ViewerEffectHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();
            ViewerEffectPacket effect = (ViewerEffectPacket)packet;

            for (ViewerEffectPacket.EffectBlock block : effect.Effect)
            {
                EffectType type = EffectType.get(block.Type);

                // Each ViewerEffect type uses it's own custom binary format for additional data. Fun eh?
                switch (type)
                {
                    case Text:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case Icon:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case Connector:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case FlexibleObject:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case AnimalControls:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case AnimationObject:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case Cloth:
                        JLogger.warn("Received a ViewerEffect of type " + type.toString() + ", implement me!");
                        break;
                    case Glow:
                        JLogger.warn("Received a Glow ViewerEffect which is not implemented yet");
                        break;
                    case Beam:
                    case Point:
                    case Trail:
                    case Sphere:
                    case Spiral:
                    case Edit:
                        if (onViewerEffect != 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.raiseEvent(new ViewerEffectEventArgs(type, sourceAvatar, targetObject, targetPos, block.Duration, block.ID));
                            }
                            else
                            {
                                JLogger.warn("Received a " + type.toString() +
                                    " ViewerEffect with an incorrect TypeData size of " +
                                    block.TypeData.length + " bytes");
                            }
                        }
                        break;
                    case LookAt:
                        if (onViewerEffectLookAt != 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.get(block.TypeData[56]);

                                onViewerEffectLookAt.raiseEvent(new ViewerEffectLookAtEventArgs(sourceAvatar, targetObject, targetPos, lookAt,
                                    block.Duration, block.ID));
                            }
                            else
                            {
                                JLogger.warn("Received a LookAt ViewerEffect with an incorrect TypeData size of " +
                                    block.TypeData.length + " bytes");
                            }
                        }
                        break;
                    case PointAt:
                        if (onViewerEffectPointAt != 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.get(block.TypeData[56]);

                                onViewerEffectPointAt.raiseEvent(new ViewerEffectPointAtEventArgs(e.getSimulator(), sourceAvatar, targetObject, targetPos,
                                    pointAt, block.Duration, block.ID));
                            }
                            else
                            {
                                JLogger.warn("Received a PointAt ViewerEffect with an incorrect TypeData size of " +
                                    block.TypeData.length + " bytes");
                            }
                        }
                        break;
                    default:
                        JLogger.warn("Received a ViewerEffect with an unknown type " + type);
                        break;
                }
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarPicksReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarPicksReply == null)
            {
                return;
            }
            Packet packet = e.getPacket();

            AvatarPicksReplyPacket p = (AvatarPicksReplyPacket)packet;
            Map<UUID, String> picks = new HashMap<UUID, String>();

            for (AvatarPicksReplyPacket.DataBlock b : p.Data)
            {
                picks.put(b.PickID, Utils.bytesWithTrailingNullByteToString(b.PickName));
            }

            onAvatarPicksReply.raiseEvent(new AvatarPicksReplyEventArgs(p.AgentData.TargetID, picks));
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void PickInfoReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onPickInfoReply != null)
            {
                Packet packet = e.getPacket();
                PickInfoReplyPacket p = (PickInfoReplyPacket)packet;
                ProfilePick ret = new ProfilePick();
                ret.CreatorID = p.Data.CreatorID;
                ret.Desc = Utils.bytesWithTrailingNullByteToString(p.Data.Desc);
                ret.Enabled = p.Data.Enabled;
                ret.Name = Utils.bytesWithTrailingNullByteToString(p.Data.Name);
                ret.OriginalName = Utils.bytesWithTrailingNullByteToString(p.Data.OriginalName);
                ret.ParcelID = p.Data.ParcelID;
                ret.PickID = p.Data.PickID;
                ret.PosGlobal = p.Data.PosGlobal;
                ret.SimName = Utils.bytesWithTrailingNullByteToString(p.Data.SimName);
                ret.SnapshotID = p.Data.SnapshotID;
                ret.SortOrder = p.Data.SortOrder;
                ret.TopPick = p.Data.TopPick;
                ret.User = Utils.bytesWithTrailingNullByteToString(p.Data.User);

                onPickInfoReply.raiseEvent(new PickInfoReplyEventArgs(ret.PickID, ret));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void AvatarClassifiedReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarClassifiedReply != null)
            {
                Packet packet = e.getPacket();
                AvatarClassifiedReplyPacket p = (AvatarClassifiedReplyPacket)packet;
                Map<UUID, String> classifieds = new HashMap<UUID, String>();

                for (AvatarClassifiedReplyPacket.DataBlock b : p.Data)
                {
                    classifieds.put(b.ClassifiedID, Utils.bytesWithTrailingNullByteToString(b.Name));
                }

                onAvatarClassifiedReply.raiseEvent(new AvatarClassifiedReplyEventArgs(p.AgentData.TargetID, classifieds));
            }
        }

        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void ClassifiedInfoReplyHandler(Object sender, PacketReceivedEventArgs e) throws UnsupportedEncodingException
        {
            if (onAvatarClassifiedReply != null)
            {
                Packet packet = e.getPacket();
                ClassifiedInfoReplyPacket p = (ClassifiedInfoReplyPacket)packet;
                ClassifiedAd ret = new ClassifiedAd();
                ret.Desc = Utils.bytesWithTrailingNullByteToString(p.Data.Desc);
                ret.Name = Utils.bytesWithTrailingNullByteToString(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.raiseEvent(new ClassifiedInfoReplyEventArgs(ret.ClassifiedID, ret));
            }
        }

        //endregion Packet Handlers
}
TOP

Related Classes of com.ngt.jopenmetaverse.shared.sim.AvatarManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.