Package com.ngt.jopenmetaverse.shared.sim

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

/**
* 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.math.BigInteger;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Observable;

import com.ngt.jopenmetaverse.shared.exception.nm.InventoryException;
import com.ngt.jopenmetaverse.shared.protocol.AcceptFriendshipPacket;
import com.ngt.jopenmetaverse.shared.protocol.ChangeUserRightsPacket;
import com.ngt.jopenmetaverse.shared.protocol.DeclineFriendshipPacket;
import com.ngt.jopenmetaverse.shared.protocol.FindAgentPacket;
import com.ngt.jopenmetaverse.shared.protocol.GenericMessagePacket;
import com.ngt.jopenmetaverse.shared.protocol.GrantUserRightsPacket;
import com.ngt.jopenmetaverse.shared.protocol.Helpers;
import com.ngt.jopenmetaverse.shared.protocol.OfflineNotificationPacket;
import com.ngt.jopenmetaverse.shared.protocol.OnlineNotificationPacket;
import com.ngt.jopenmetaverse.shared.protocol.Packet;
import com.ngt.jopenmetaverse.shared.protocol.PacketType;
import com.ngt.jopenmetaverse.shared.protocol.TerminateFriendshipPacket;
import com.ngt.jopenmetaverse.shared.protocol.TrackAgentPacket;
import com.ngt.jopenmetaverse.shared.sim.AgentManager.InstantMessageDialog;
import com.ngt.jopenmetaverse.shared.sim.AgentManager.InstantMessageOnline;
import com.ngt.jopenmetaverse.shared.sim.events.*;
import com.ngt.jopenmetaverse.shared.sim.events.am.InstantMessageEventArgs;
import com.ngt.jopenmetaverse.shared.sim.events.avm.UUIDNameReplyEventArgs;
import com.ngt.jopenmetaverse.shared.sim.events.friends.*;
import com.ngt.jopenmetaverse.shared.sim.friends.FriendInfo;
import com.ngt.jopenmetaverse.shared.sim.friends.FriendRights;
import com.ngt.jopenmetaverse.shared.sim.login.BuddyListEntry;
import com.ngt.jopenmetaverse.shared.sim.login.LoginProgressEventArgs;
import com.ngt.jopenmetaverse.shared.sim.login.LoginResponseCallbackArg;
import com.ngt.jopenmetaverse.shared.sim.login.LoginResponseData;
import com.ngt.jopenmetaverse.shared.sim.login.LoginStatus;
import com.ngt.jopenmetaverse.shared.types.Action;
import com.ngt.jopenmetaverse.shared.types.Enums.AssetType;
import com.ngt.jopenmetaverse.shared.types.UUID;
import com.ngt.jopenmetaverse.shared.types.Vector3;
import com.ngt.jopenmetaverse.shared.util.JLogger;
import com.ngt.jopenmetaverse.shared.util.Utils;


/// <summary>
/// This class is used to add and remove avatars from your friends list and to manage their permission. 
/// </summary>
public class FriendsManager {

  private EventObservable<FriendInfoEventArgs> onFriendOnline = new EventObservable<FriendInfoEventArgs>();
  public void registerOnFriendOnline(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendOnline.addObserver(o);
  }
  public void unregisterOnFriendOnline(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendOnline.deleteObserver(o);
  }
  private EventObservable<FriendInfoEventArgs> onFriendOffline = new EventObservable<FriendInfoEventArgs>();
  public void registerOnFriendOffline(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendOffline.addObserver(o);
  }
  public void unregisterOnFriendOffline(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendOffline.deleteObserver(o);
  }
  private EventObservable<FriendInfoEventArgs> onFriendRightsUpdate = new EventObservable<FriendInfoEventArgs>();
  public void registerOnFriendRightsUpdate(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendRightsUpdate.addObserver(o);
  }
  public void unregisterOnFriendRightsUpdate(EventObserver<FriendInfoEventArgs> o)
  {
    onFriendRightsUpdate.deleteObserver(o);
  }
  private EventObservable<FriendNamesEventArgs> onFriendNames = new EventObservable<FriendNamesEventArgs>();
  public void registerOnFriendNames(EventObserver<FriendNamesEventArgs> o)
  {
    onFriendNames.addObserver(o);
  }
  public void unregisterOnFriendNames(EventObserver<FriendNamesEventArgs> o)
  {
    onFriendNames.deleteObserver(o);
  }
  private EventObservable<FriendshipOfferedEventArgs> onFriendshipOffered = new EventObservable<FriendshipOfferedEventArgs>();
  public void registerOnFriendshipOffered(EventObserver<FriendshipOfferedEventArgs> o)
  {
    onFriendshipOffered.addObserver(o);
  }
  public void unregisterOnFriendshipOffered(EventObserver<FriendshipOfferedEventArgs> o)
  {
    onFriendshipOffered.deleteObserver(o);
  }
  private EventObservable<FriendshipResponseEventArgs> onFriendshipResponse = new EventObservable<FriendshipResponseEventArgs>();
  public void registerOnFriendshipResponse(EventObserver<FriendshipResponseEventArgs> o)
  {
    onFriendshipResponse.addObserver(o);
  }
  public void unregisterOnFriendshipResponse(EventObserver<FriendshipResponseEventArgs> o)
  {
    onFriendshipResponse.deleteObserver(o);
  }
  private EventObservable<FriendshipTerminatedEventArgs> onFriendshipTerminated = new EventObservable<FriendshipTerminatedEventArgs>();
  public void registerOnFriendshipTerminated(EventObserver<FriendshipTerminatedEventArgs> o)
  {
    onFriendshipTerminated.addObserver(o);
  }
  public void unregisterOnFriendshipTerminated(EventObserver<FriendshipTerminatedEventArgs> o)
  {
    onFriendshipTerminated.deleteObserver(o);
  }
  private EventObservable<FriendFoundReplyEventArgs> onFriendFoundReply = new EventObservable<FriendFoundReplyEventArgs>();
  public void registerOnFriendFoundReply(EventObserver<FriendFoundReplyEventArgs> o)
  {
    onFriendFoundReply.addObserver(o);
  }
  public void unregisterOnFriendFoundReply(EventObserver<FriendFoundReplyEventArgs> o)
  {
    onFriendFoundReply.deleteObserver(o);
  }

 
//        //region Delegates
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendInfoEventArgs> m_FriendOnline;
//
//        /// <summary>Raises the FriendOnline event</summary>
//        /// <param name="e">A FriendInfoEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendOnline(FriendInfoEventArgs e)
//        {
//            EventHandler<FriendInfoEventArgs> handler = m_FriendOnline;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendOnlineLock = new object();
//
//        /// <summary>Raised when the simulator sends notification one of the members in our friends list comes online</summary>
//        public event EventHandler<FriendInfoEventArgs> FriendOnline
//        {
//            add { lock (m_FriendOnlineLock) { m_FriendOnline += value; } }
//            remove { lock (m_FriendOnlineLock) { m_FriendOnline -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendInfoEventArgs> m_FriendOffline;
//
//        /// <summary>Raises the FriendOffline event</summary>
//        /// <param name="e">A FriendInfoEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendOffline(FriendInfoEventArgs e)
//        {
//            EventHandler<FriendInfoEventArgs> handler = m_FriendOffline;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendOfflineLock = new object();
//
//        /// <summary>Raised when the simulator sends notification one of the members in our friends list goes offline</summary>
//        public event EventHandler<FriendInfoEventArgs> FriendOffline
//        {
//            add { lock (m_FriendOfflineLock) { m_FriendOffline += value; } }
//            remove { lock (m_FriendOfflineLock) { m_FriendOffline -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendInfoEventArgs> m_FriendRights;
//
//        /// <summary>Raises the FriendRightsUpdate event</summary>
//        /// <param name="e">A FriendInfoEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendRights(FriendInfoEventArgs e)
//        {
//            EventHandler<FriendInfoEventArgs> handler = m_FriendRights;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendRightsLock = new object();
//
//        /// <summary>Raised when the simulator sends notification one of the members in our friends list grants or revokes permissions</summary>
//        public event EventHandler<FriendInfoEventArgs> FriendRightsUpdate
//        {
//            add { lock (m_FriendRightsLock) { m_FriendRights += value; } }
//            remove { lock (m_FriendRightsLock) { m_FriendRights -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendNamesEventArgs> m_FriendNames;
//
//        /// <summary>Raises the FriendNames event</summary>
//        /// <param name="e">A FriendNamesEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendNames(FriendNamesEventArgs e)
//        {
//            EventHandler<FriendNamesEventArgs> handler = m_FriendNames;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendNamesLock = new object();
//
//        /// <summary>Raised when the simulator sends us the names on our friends list</summary>
//        public event EventHandler<FriendNamesEventArgs> FriendNames
//        {
//            add { lock (m_FriendNamesLock) { m_FriendNames += value; } }
//            remove { lock (m_FriendNamesLock) { m_FriendNames -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendshipOfferedEventArgs> m_FriendshipOffered;
//
//        /// <summary>Raises the FriendshipOffered event</summary>
//        /// <param name="e">A FriendshipOfferedEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendshipOffered(FriendshipOfferedEventArgs e)
//        {
//            EventHandler<FriendshipOfferedEventArgs> handler = m_FriendshipOffered;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendshipOfferedLock = new object();
//
//        /// <summary>Raised when the simulator sends notification another agent is offering us friendship</summary>
//        public event EventHandler<FriendshipOfferedEventArgs> FriendshipOffered
//        {
//            add { lock (m_FriendshipOfferedLock) { m_FriendshipOffered += value; } }
//            remove { lock (m_FriendshipOfferedLock) { m_FriendshipOffered -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendshipResponseEventArgs> m_FriendshipResponse;
//
//        /// <summary>Raises the FriendshipResponse event</summary>
//        /// <param name="e">A FriendshipResponseEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendshipResponse(FriendshipResponseEventArgs e)
//        {
//            EventHandler<FriendshipResponseEventArgs> handler = m_FriendshipResponse;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendshipResponseLock = new object();
//
//        /// <summary>Raised when a request we sent to friend another agent is accepted or declined</summary>
//        public event EventHandler<FriendshipResponseEventArgs> FriendshipResponse
//        {
//            add { lock (m_FriendshipResponseLock) { m_FriendshipResponse += value; } }
//            remove { lock (m_FriendshipResponseLock) { m_FriendshipResponse -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendshipTerminatedEventArgs> m_FriendshipTerminated;
//
//        /// <summary>Raises the FriendshipTerminated event</summary>
//        /// <param name="e">A FriendshipTerminatedEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendshipTerminated(FriendshipTerminatedEventArgs e)
//        {
//            EventHandler<FriendshipTerminatedEventArgs> handler = m_FriendshipTerminated;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendshipTerminatedLock = new object();
//
//        /// <summary>Raised when the simulator sends notification one of the members in our friends list has terminated
//        /// our friendship</summary>
//        public event EventHandler<FriendshipTerminatedEventArgs> FriendshipTerminated
//        {
//            add { lock (m_FriendshipTerminatedLock) { m_FriendshipTerminated += value; } }
//            remove { lock (m_FriendshipTerminatedLock) { m_FriendshipTerminated -= value; } }
//        }
//
//        /// <summary>The event subscribers. null if no subcribers</summary>
//        private EventHandler<FriendFoundReplyEventArgs> m_FriendFound;
//
//        /// <summary>Raises the FriendFoundReply event</summary>
//        /// <param name="e">A FriendFoundReplyEventArgs object containing the
//        /// data returned from the data server</param>
//        protected virtual void OnFriendFoundReply(FriendFoundReplyEventArgs e)
//        {
//            EventHandler<FriendFoundReplyEventArgs> handler = m_FriendFound;
//            if (handler != null)
//                handler(this, e);
//        }
//
//        /// <summary>Thread sync lock object</summary>
//        private readonly object m_FriendFoundLock = new object();
//
//        /// <summary>Raised when the simulator sends the location of a friend we have
//        /// requested map location info for</summary>
//        public event EventHandler<FriendFoundReplyEventArgs> FriendFoundReply
//        {
//            add { lock (m_FriendFoundLock) { m_FriendFound += value; } }
//            remove { lock (m_FriendFoundLock) { m_FriendFound -= value; } }
//        }
//
//        //endregion Delegates
//
//        //region Events
//
//        //endregion Events
//
        private GridClient Client;
        /// <summary>
        /// A dictionary of key/value pairs containing known friends of this avatar.
        ///
        /// The Key is the <seealso cref="UUID"/> of the friend, the value is a <seealso cref="FriendInfo"/>
        /// object that contains detailed information including permissions you have and have given to the friend
        /// </summary>
        public InternalDictionary<UUID, FriendInfo> FriendList = new InternalDictionary<UUID, FriendInfo>();

        /// <summary>
        /// A Dictionary of key/value pairs containing current pending frienship offers.
        ///
        /// The key is the <seealso cref="UUID"/> of the avatar making the request,
        /// the value is the <seealso cref="UUID"/> of the request which is used to accept
        /// or decline the friendship offer
        /// </summary>
        public InternalDictionary<UUID, UUID> FriendRequests = new InternalDictionary<UUID, UUID>();

        /// <summary>
        /// Internal constructor
        /// </summary>
        /// <param name="client">A reference to the GridClient Object</param>
        public FriendsManager(GridClient client)
        {
          Client = client;

          // Client.network.LoginProgress += Network_OnConnect;           
          Client.network.RegisterLoginProgressCallback(new EventObserver<LoginProgressEventArgs>()
              {
            @Override
            public void handleEvent(Observable o, LoginProgressEventArgs e) {
              Network_OnConnect(o, e);
            }});

          // Client.avatars.UUIDNameReply += new EventHandler<UUIDNameReplyEventArgs>(Avatars_OnAvatarNames);
          Client.avatars.registerOnUUIDNameReply(new EventObserver<UUIDNameReplyEventArgs>()
              {
            @Override
            public void handleEvent(Observable sender,
                UUIDNameReplyEventArgs arg) {
              Avatars_OnAvatarNames(sender, arg);
            }
              }
              );

          // Client.self.IM += Self_IM;
          Client.self.registerIM(new EventObserver<InstantMessageEventArgs>()
              {
            @Override
            public void handleEvent(Observable o,
                InstantMessageEventArgs arg) {
              try {
                Self_IM(o, arg);}
              catch(Exception e) {JLogger.warn(Utils.getExceptionStackTraceAsString(e));}
            }
              });

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

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

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

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

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

          // Client.network.RegisterLoginResponseCallback(new NetworkManager.LoginResponseCallback(Network_OnLoginResponse),
          //                new string[] { "buddy-list" });           
          Client.network.RegisterLoginResponseCallback(new EventObserver<LoginResponseCallbackArg>()
              {
            public void handleEvent(Observable arg0, LoginResponseCallbackArg arg1) {
              LoginResponseCallbackArg obj = (LoginResponseCallbackArg)arg1;
              Network_OnLoginResponse(obj.isLoginSuccess(), obj.isRedirect(),
                  obj.getMessage(), obj.getReason(), obj.getReplyData());
           
              }, new String[] { "buddy-list" });
        }

        //region Public Methods

        /// <summary>
        /// Accept a friendship request
        /// </summary>
        /// <param name="fromAgentID">agentID of avatatar to form friendship with</param>
        /// <param name="imSessionID">imSessionID of the friendship request message</param>
        public void AcceptFriendship(UUID fromAgentID, UUID imSessionID) throws InventoryException
        {
          UUID callingCardFolder = Client.inventory.FindFolderForType(AssetType.CallingCard);

            AcceptFriendshipPacket request = new AcceptFriendshipPacket();
            request.AgentData.AgentID = Client.self.getAgentID();
            request.AgentData.SessionID = Client.self.getSessionID();
            request.TransactionBlock.TransactionID = imSessionID;
            request.FolderData = new AcceptFriendshipPacket.FolderDataBlock[1];
            request.FolderData[0] = new AcceptFriendshipPacket.FolderDataBlock();
            request.FolderData[0].FolderID = callingCardFolder;

            Client.network.SendPacket(request);

            FriendInfo friend = new FriendInfo(fromAgentID, FriendRights.get(FriendRights.CanSeeOnline.getIndex()),
                FriendRights.get(FriendRights.CanSeeOnline.getIndex()));

            if (!FriendList.containsKey(fromAgentID))
                FriendList.add(friend.getUUID(), friend);

            if (FriendRequests.containsKey(fromAgentID))
                FriendRequests.remove(fromAgentID);

            Client.avatars.RequestAvatarName(fromAgentID);
        }

        /// <summary>
        /// Decline a friendship request
        /// </summary>
        /// <param name="fromAgentID"><seealso cref="UUID"/> of friend</param>
        /// <param name="imSessionID">imSessionID of the friendship request message</param>
        public void DeclineFriendship(UUID fromAgentID, UUID imSessionID)
        {
            DeclineFriendshipPacket request = new DeclineFriendshipPacket();
            request.AgentData.AgentID = Client.self.getAgentID();
            request.AgentData.SessionID = Client.self.getSessionID();
            request.TransactionBlock.TransactionID = imSessionID;
            Client.network.SendPacket(request);

            if (FriendRequests.containsKey(fromAgentID))
                FriendRequests.remove(fromAgentID);
        }

        /// <summary>
        /// Overload: Offer friendship to an avatar.
        /// </summary>
        /// <param name="agentID">System ID of the avatar you are offering friendship to</param>
        public void OfferFriendship(UUID agentID)
        {
            OfferFriendship(agentID, "Do ya wanna be my buddy?");
        }

        /// <summary>
        /// Offer friendship to an avatar.
        /// </summary>
        /// <param name="agentID">System ID of the avatar you are offering friendship to</param>
        /// <param name="message">A message to send with the request</param>
        public void OfferFriendship(UUID agentID, String message)
        {
            Client.self.InstantMessage(Client.self.getName(),
                agentID,
                message,
                UUID.Random(),
                InstantMessageDialog.FriendshipOffered,
                InstantMessageOnline.Offline,
                Client.self.getSimPosition(),
                Client.network.getCurrentSim().ID,
                null);
        }


        /// <summary>
        /// Terminate a friendship with an avatar
        /// </summary>
        /// <param name="agentID">System ID of the avatar you are terminating the friendship with</param>
        public void TerminateFriendship(UUID agentID)
        {
            if (FriendList.containsKey(agentID))
            {
                TerminateFriendshipPacket request = new TerminateFriendshipPacket();
                request.AgentData.AgentID = Client.self.getAgentID();
                request.AgentData.SessionID = Client.self.getSessionID();
                request.ExBlock.OtherID = agentID;

                Client.network.SendPacket(request);

                if (FriendList.containsKey(agentID))
                    FriendList.remove(agentID);
            }
        }
        /// <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>
        private void TerminateFriendshipHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();
            TerminateFriendshipPacket itsOver = (TerminateFriendshipPacket)packet;
            String name = "";

            if (FriendList.containsKey(itsOver.ExBlock.OtherID))
            {
                name = FriendList.get(itsOver.ExBlock.OtherID).getName();
                FriendList.remove(itsOver.ExBlock.OtherID);
            }

            if (onFriendshipTerminated != null)
            {
                onFriendshipTerminated.raiseEvent(new FriendshipTerminatedEventArgs(itsOver.ExBlock.OtherID, name));
            }
        }

        /// <summary>
        /// Change the rights of a friend avatar.
        /// </summary>
        /// <param name="friendID">the <seealso cref="UUID"/> of the friend</param>
        /// <param name="rights">the new rights to give the friend</param>
        /// <remarks>This method will implicitly set the rights to those passed in the rights parameter.</remarks>
        public void GrantRights(UUID friendID, EnumSet<FriendRights> rights)
        {
            GrantUserRightsPacket request = new GrantUserRightsPacket();
            request.AgentData.AgentID = Client.self.getAgentID();
            request.AgentData.SessionID = Client.self.getSessionID();
            request.Rights = new GrantUserRightsPacket.RightsBlock[1];
            request.Rights[0] = new GrantUserRightsPacket.RightsBlock();
            request.Rights[0].AgentRelated = friendID;
            request.Rights[0].RelatedRights = FriendRights.getIndex(rights);

            Client.network.SendPacket(request);
        }

        /// <summary>
        /// Use to map a friends location on the grid.
        /// </summary>
        /// <param name="friendID">Friends UUID to find</param>
        /// <remarks><seealso cref="E:OnFriendFound"/></remarks>
        public void MapFriend(UUID friendID)
        {
            FindAgentPacket stalk = new FindAgentPacket();
            stalk.AgentBlock.Hunter = Client.self.getAgentID();
            stalk.AgentBlock.Prey = friendID;
            stalk.AgentBlock.SpaceIP = 0; // Will be filled in by the simulator
            stalk.LocationBlock = new FindAgentPacket.LocationBlockBlock[1];
            stalk.LocationBlock[0] = new FindAgentPacket.LocationBlockBlock();
            stalk.LocationBlock[0].GlobalX = 0.0; // Filled in by the simulator
            stalk.LocationBlock[0].GlobalY = 0.0;

            Client.network.SendPacket(stalk);
        }

        /// <summary>
        /// Use to track a friends movement on the grid
        /// </summary>
        /// <param name="friendID">Friends Key</param>
        public void TrackFriend(UUID friendID)
        {
            TrackAgentPacket stalk = new TrackAgentPacket();
            stalk.AgentData.AgentID = Client.self.getAgentID();
            stalk.AgentData.SessionID = Client.self.getSessionID();
            stalk.TargetData.PreyID = friendID;

            Client.network.SendPacket(stalk);
        }

        /// <summary>
        /// Ask for a notification of friend's online status
        /// </summary>
        /// <param name="friendID">Friend's UUID</param>
        public void RequestOnlineNotification(UUID friendID)
        {
            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("requestonlinenotification");
            gmp.MethodData.Invoice = UUID.Zero;
            gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
            gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
            gmp.ParamList[0].Parameter = Utils.stringToBytesWithTrailingNullByte(friendID.toString());

            Client.network.SendPacket(gmp);
        }

        //endregion

        //region Internal events

        private void Network_OnConnect(Object sender, LoginProgressEventArgs e)
        {
            if (e.getStatus() != LoginStatus.Success)
            {
                return;
            }

            final List<UUID> names = new ArrayList<UUID>();

            if (FriendList.getCount() > 0)
            {
              FriendList.foreach(new Action<Entry<UUID, FriendInfo>>()
              {
          public void execute(Entry<UUID, FriendInfo> kvp) {
                        if (Utils.isNullOrEmpty(kvp.getValue().getName()))
                            names.add(kvp.getKey());
          }
              }
              );
                Client.avatars.RequestAvatarNames(names);
            }
        }


        /// <summary>
        /// This handles the asynchronous response of a RequestAvatarNames call.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">names cooresponding to the the list of IDs sent the the RequestAvatarNames call.</param>
        private void Avatars_OnAvatarNames(Object sender, UUIDNameReplyEventArgs e)
        {
            Map<UUID, String> newNames = new HashMap<UUID, String>();

            for (Entry<UUID, String> kvp : e.getNames().entrySet())
            {
                FriendInfo friend;
                synchronized (FriendList.getDictionary())
                {
                    if ((friend = FriendList.get(kvp.getKey()))!=null)
                    {
                        if (friend.getName() == null)
                            newNames.put(kvp.getKey(), kvp.getValue());

                        friend.setName(kvp.getValue());
                        FriendList.add(kvp.getKey(), friend);
                    }
                }
            }

            if (newNames.size() > 0 && onFriendNames != null)
            {
                onFriendNames.raiseEvent(new FriendNamesEventArgs(newNames));
            }
        }
        //endregion

        //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 OnlineNotificationHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();
            if (packet.Type == PacketType.OnlineNotification)
            {
                OnlineNotificationPacket notification = ((OnlineNotificationPacket)packet);

                for (OnlineNotificationPacket.AgentBlockBlock block : notification.AgentBlock)
                {
                    FriendInfo friend;
                    synchronized (FriendList.getDictionary())
                    {
                        if (!FriendList.containsKey(block.AgentID))
                        {
                            friend = new FriendInfo(block.AgentID, FriendRights.get(FriendRights.CanSeeOnline.getIndex()),
                                FriendRights.get(FriendRights.CanSeeOnline.getIndex()));
                            FriendList.add(block.AgentID, friend);
                        }
                        else
                        {
                            friend = FriendList.get(block.AgentID);
                        }
                    }

                    boolean doNotify = !friend.isOnline();
                    friend.setIsOnline(true);

                    if (onFriendOnline != null && doNotify)
                    {
                        onFriendOnline.raiseEvent(new FriendInfoEventArgs(friend));
                    }
                }
            }
        }

        /// <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 OfflineNotificationHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();
            if (packet.Type == PacketType.OfflineNotification)
            {
                OfflineNotificationPacket notification = (OfflineNotificationPacket)packet;

                for (OfflineNotificationPacket.AgentBlockBlock block : notification.AgentBlock)
                {
                    FriendInfo friend = new FriendInfo(block.AgentID, FriendRights.get(FriendRights.CanSeeOnline.getIndex()),
                        FriendRights.get(FriendRights.CanSeeOnline.getIndex()));

                    synchronized (FriendList.getDictionary())
                    {
                        if (!FriendList.containsKey(block.AgentID))
                            FriendList.add(block.AgentID, friend);

                        friend = FriendList.get(block.AgentID);
                    }

                    friend.setIsOnline(false);

                    if (onFriendOffline != null)
                    {
                        onFriendOffline.raiseEvent(new FriendInfoEventArgs(friend));
                    }
                }
            }
        }


        /// <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>
        private void ChangeUserRightsHandler(Object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.getPacket();
            if (packet.Type == PacketType.ChangeUserRights)
            {
                FriendInfo friend;
                ChangeUserRightsPacket rights = (ChangeUserRightsPacket)packet;

                for (ChangeUserRightsPacket.RightsBlock block : rights.Rights)
                {
                    EnumSet<FriendRights> newRights = FriendRights.get(block.RelatedRights);
                    if ((friend = FriendList.get(block.AgentRelated) )!= null)
                    {
                        friend.setTheirFriendRights(newRights);
                        if (onFriendRightsUpdate != null)
                        {
                          onFriendRightsUpdate.raiseEvent(new FriendInfoEventArgs(friend));
                        }
                    }
                    else if (block.AgentRelated.equals(Client.self.getAgentID()))
                    {
                        if (( friend = FriendList.get(rights.AgentData.AgentID))!=null)
                        {
                            friend.setMyFriendRights(newRights);
                            if (onFriendRightsUpdate != null)
                            {
                              onFriendRightsUpdate.raiseEvent(new FriendInfoEventArgs(friend));
                            }
                        }
                    }
                }
            }
        }

        /// <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>
        public void OnFindAgentReplyHandler(Object sender, PacketReceivedEventArgs e)
        {
            if (onFriendFoundReply != null)
            {
                Packet packet = e.getPacket();
                FindAgentPacket reply = (FindAgentPacket)packet;

                float[] xy = new float[2];
                UUID prey = reply.AgentBlock.Prey;
                BigInteger regionHandle = Helpers.GlobalPosToRegionHandle((float)reply.LocationBlock[0].GlobalX,
                    (float)reply.LocationBlock[0].GlobalY, xy);
                Vector3 xyz = new Vector3(xy[0], xy[0], 0f);

                onFriendFoundReply.raiseEvent(new FriendFoundReplyEventArgs(prey, regionHandle, xyz));
            }
        }

        //endregion

        private void Self_IM(Object sender, InstantMessageEventArgs e)
        {
            if (e.getIM().Dialog == InstantMessageDialog.FriendshipOffered)
            {
                if (onFriendshipOffered != null)
                {
                    if (FriendRequests.containsKey(e.getIM().FromAgentID))
                        FriendRequests.add(e.getIM().FromAgentID,  e.getIM().IMSessionID);
                    else
                        FriendRequests.add(e.getIM().FromAgentID, e.getIM().IMSessionID);

                    onFriendshipOffered.raiseEvent(new FriendshipOfferedEventArgs(e.getIM().FromAgentID, e.getIM().FromAgentName, e.getIM().IMSessionID));
                }
            }
            else if (e.getIM().Dialog == InstantMessageDialog.FriendshipAccepted)
            {
                FriendInfo friend = new FriendInfo(e.getIM().FromAgentID, FriendRights.get(FriendRights.CanSeeOnline.getIndex()),
                    FriendRights.get(FriendRights.CanSeeOnline.getIndex()));
                friend.setName( e.getIM().FromAgentName);
                synchronized (FriendList.getDictionary())
                {FriendList.add(friend.getUUID(), friend);}

                if (onFriendshipResponse != null)
                {
                    onFriendshipResponse.raiseEvent(new FriendshipResponseEventArgs(e.getIM().FromAgentID, e.getIM().FromAgentName, true));
                }
                RequestOnlineNotification(e.getIM().FromAgentID);
            }
            else if (e.getIM().Dialog == InstantMessageDialog.FriendshipDeclined)
            {
                if (onFriendshipResponse != null)
                {
                    onFriendshipResponse.raiseEvent(new FriendshipResponseEventArgs(e.getIM().FromAgentID, e.getIM().FromAgentName, false));
                }
            }
        }

        /// <summary>
        /// Populate FriendList <seealso cref="InternalDictionary"/> with data from the login reply
        /// </summary>
        /// <param name="loginSuccess">true if login was successful</param>
        /// <param name="redirect">true if login request is requiring a redirect</param>
        /// <param name="message">A String containing the response to the login request</param>
        /// <param name="reason">A String containing the reason for the request</param>
        /// <param name="replyData">A <seealso cref="LoginResponseData"/> object containing the decoded
        /// reply from the login server</param>
        private void Network_OnLoginResponse(boolean loginSuccess, boolean redirect, String message, String reason,
            LoginResponseData replyData)
        {
            int uuidLength = UUID.Zero.toString().length();

            if (loginSuccess && replyData.BuddyList != null)
            {
                for (BuddyListEntry buddy : replyData.BuddyList)
                {
                    UUID bubid;
                    String id = buddy.buddy_id.length() > uuidLength ? buddy.buddy_id.substring(0, uuidLength) : buddy.buddy_id;
                    if ((bubid = UUID.Parse(id))!=null)
                    {
                        synchronized (FriendList.getDictionary())
                        {
                            if (!FriendList.containsKey(bubid))
                            {
                                FriendList.add(bubid, new FriendInfo(bubid,
                                    FriendRights.get(buddy.buddy_rights_given),
                                    FriendRights.get(buddy.buddy_rights_has)));
                            }
                        }
                    }
                }
            }
        }
    }
TOP

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

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.