From 59dec2f989474158c94a2383b150c25d132777aa Mon Sep 17 00:00:00 2001
From: unknown
Date: Thu, 20 May 2010 11:51:57 -0700
Subject: * Added sessionID to IGridUserService.SetLastPosition(), as some
 connectors will want to track position against sessionID instead of userID *
 Updated SimianPresenceServiceConnector to use the new LoggedOut/SetHome/etc
 methods and only update session position on parcel crossing

---
 .../GridUser/GridUserServiceConnector.cs           |   2 +-
 .../SimianGrid/SimianActivityDetector.cs           | 113 +++++++++++++
 .../SimianGrid/SimianPresenceServiceConnector.cs   | 187 +++++++--------------
 OpenSim/Services/Interfaces/IGridUserService.cs    |   2 +-
 .../Services/UserAccountService/GridUserService.cs |   2 +-
 5 files changed, 181 insertions(+), 125 deletions(-)
 create mode 100644 OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs

(limited to 'OpenSim/Services')

diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
index b4500a5..f222e31 100644
--- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
@@ -123,7 +123,7 @@ namespace OpenSim.Services.Connectors
             return Set(sendData, userID, regionID, position, lookAt);
         }
 
-        public bool SetLastPosition(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
+        public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
         {
             Dictionary<string, object> sendData = new Dictionary<string, object>();
             //sendData["SCOPEID"] = scopeID.ToString();
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
new file mode 100644
index 0000000..8cc5671
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using OpenMetaverse;
+using log4net;
+
+namespace OpenSim.Services.Connectors.SimianGrid
+{
+    public class SimianActivityDetector
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private IGridUserService m_GridUserService;
+        private Scene m_aScene;
+
+        public SimianActivityDetector(IGridUserService guservice)
+        {
+            m_GridUserService = guservice;
+            m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Started");
+        }
+
+        public void AddRegion(Scene scene)
+        {
+            // For now the only events we listen to are these
+            // But we could trigger the position update more often
+            scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
+            scene.EventManager.OnNewClient += OnNewClient;
+            scene.EventManager.OnAvatarEnteringNewParcel += OnEnteringNewParcel;
+
+            if (m_aScene == null)
+                m_aScene = scene;
+        }
+
+        public void RemoveRegion(Scene scene)
+        {
+            scene.EventManager.OnMakeRootAgent -= OnMakeRootAgent;
+            scene.EventManager.OnNewClient -= OnNewClient;
+            scene.EventManager.OnAvatarEnteringNewParcel -= OnEnteringNewParcel;
+        }
+
+        public void OnMakeRootAgent(ScenePresence sp)
+        {
+            m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
+            m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
+        }
+
+        public void OnNewClient(IClientAPI client)
+        {
+            client.OnConnectionClosed += OnConnectionClose;
+        }
+
+        public void OnConnectionClose(IClientAPI client)
+        {
+            if (client.IsLoggingOut)
+            {
+                object sp = null;
+                Vector3 position = new Vector3(128, 128, 0);
+                Vector3 lookat = new Vector3(0, 1, 0);
+
+                if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
+                {
+                    if (sp is ScenePresence)
+                    {
+                        if (((ScenePresence)sp).IsChildAgent)
+                            return;
+
+                        position = ((ScenePresence)sp).AbsolutePosition;
+                        lookat = ((ScenePresence)sp).Lookat;
+                    }
+                }
+
+                m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
+                m_GridUserService.LoggedOut(client.AgentId.ToString(), client.Scene.RegionInfo.RegionID, position, lookat);
+            }
+
+        }
+
+        void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID)
+        {
+            m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
+        }
+    }
+}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
index b86c45c..ec9cf67 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -58,6 +58,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
                 MethodBase.GetCurrentMethod().DeclaringType);
 
         private string m_serverUrl = String.Empty;
+        private SimianActivityDetector m_activityDetector;
 
         #region ISharedRegionModule
 
@@ -66,7 +67,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
         public void PostInitialise() { }
         public void Close() { }
 
-        public SimianPresenceServiceConnector() { }
+        public SimianPresenceServiceConnector() { m_activityDetector = new SimianActivityDetector(this); }
         public string Name { get { return "SimianPresenceServiceConnector"; } }
         public void AddRegion(Scene scene)
         {
@@ -75,9 +76,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
                 scene.RegisterModuleInterface<IPresenceService>(this);
                 scene.RegisterModuleInterface<IGridUserService>(this);
 
-                scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler;
-                scene.EventManager.OnNewClient += NewClientHandler;
-                scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler;
+                m_activityDetector.AddRegion(scene);
 
                 LogoutRegionAgents(scene.RegionInfo.RegionID);
             }
@@ -89,9 +88,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
                 scene.UnregisterModuleInterface<IPresenceService>(this);
                 scene.UnregisterModuleInterface<IGridUserService>(this);
 
-                scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler;
-                scene.EventManager.OnNewClient -= NewClientHandler;
-                scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler;
+                m_activityDetector.RemoveRegion(scene);
 
                 LogoutRegionAgents(scene.RegionInfo.RegionID);
             }
@@ -193,29 +190,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
 
         public bool ReportAgent(UUID sessionID, UUID regionID)
         {
-            return ReportAgent(sessionID, regionID, Vector3.Zero, Vector3.Zero);
-        }
-
-        protected bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
-        {
-            //m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID);
-
-            NameValueCollection requestArgs = new NameValueCollection
-            {
-                { "RequestMethod", "UpdateSession" },
-                { "SessionID", sessionID.ToString() },
-                { "SceneID", regionID.ToString() },
-                { "ScenePosition", position.ToString() },
-                { "SceneLookAt", lookAt.ToString() }
-            };
-
-            OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
-            bool success = response["Success"].AsBoolean();
-
-            if (!success)
-                m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
-
-            return success;
+            // Not needed for SimianGrid
+            return true;
         }
 
         public PresenceInfo GetAgent(UUID sessionID)
@@ -274,14 +250,27 @@ namespace OpenSim.Services.Connectors.SimianGrid
 
         public GridUserInfo LoggedIn(string userID)
         {
-            // never implemented at the sim
+            // Never implemented at the sim
             return null;
         }
 
         public bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
         {
-            // Not needed for simian grid, event handler is doing it
-            return true;
+            // Save our last position as user data
+            NameValueCollection requestArgs = new NameValueCollection
+            {
+                { "RequestMethod", "AddUserData" },
+                { "UserID", userID.ToString() },
+                { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) }
+            };
+
+            OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
+            bool success = response["Success"].AsBoolean();
+
+            if (!success)
+                m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
+
+            return success;
         }
 
         public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
@@ -304,10 +293,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
             return success;
         }
 
-        public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
+        public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
         {
-            // Not needed for simian grid, presence detection is doing it
-            return true;
+            return UpdateSession(sessionID, regionID, lastPosition, lastLookAt);
         }
 
         public GridUserInfo GetGridUserInfo(string user)
@@ -334,54 +322,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
 
         #endregion
 
-        #region Presence Detection
-
-        private void MakeRootAgentHandler(ScenePresence sp)
-        {
-            m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
-
-            ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
-            SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
-        }
-
-        private void NewClientHandler(IClientAPI client)
-        {
-            client.OnConnectionClosed += LogoutHandler;
-        }
-
-        private void SignificantClientMovementHandler(IClientAPI client)
-        {
-            ScenePresence sp;
-            if (client.Scene is Scene && ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out sp))
-                ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
-        }
-
-        private void LogoutHandler(IClientAPI client)
-        {
-            if (client.IsLoggingOut)
-            {
-                client.OnConnectionClosed -= LogoutHandler;
-
-                object obj;
-                if (client.Scene.TryGetScenePresence(client.AgentId, out obj) && obj is ScenePresence)
-                {
-                    // The avatar is still in the scene, we can get the exact logout position
-                    ScenePresence sp = (ScenePresence)obj;
-                    SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
-                }
-                else
-                {
-                    // The avatar was already removed from the scene, store LastLocation using the most recent session data
-                    m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation");
-                    SetLastLocation(client.SessionId);
-                }
-
-                LogoutAgent(client.SessionId);
-            }
-        }
-
-        #endregion Presence Detection
-
         #region Helpers
 
         private OSDMap GetUserData(UUID userID)
@@ -453,57 +393,60 @@ namespace OpenSim.Services.Connectors.SimianGrid
             return presences;
         }
 
-        /// <summary>
-        /// Fetch the last known avatar location with GetSession and persist it
-        /// as user data with AddUserData
-        /// </summary>
-        private bool SetLastLocation(UUID sessionID)
+        private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
         {
+            // Save our current location as session data
             NameValueCollection requestArgs = new NameValueCollection
             {
-                { "RequestMethod", "GetSession" },
-                { "SessionID", sessionID.ToString() }
+                { "RequestMethod", "UpdateSession" },
+                { "SessionID", sessionID.ToString() },
+                { "SceneID", regionID.ToString() },
+                { "ScenePosition", lastPosition.ToString() },
+                { "SceneLookAt", lastLookAt.ToString() }
             };
 
             OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
             bool success = response["Success"].AsBoolean();
 
-            if (success)
-            {
-                UUID userID = response["UserID"].AsUUID();
-                UUID sceneID = response["SceneID"].AsUUID();
-                Vector3 position = response["ScenePosition"].AsVector3();
-                Vector3 lookAt = response["SceneLookAt"].AsVector3();
-
-                return SetLastLocation(userID, sceneID, position, lookAt);
-            }
-            else
-            {
-                m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
-                    " while saving last location: " + response["Message"].AsString());
-            }
-
-            return success;
-        }
-
-        private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt)
-        {
-            NameValueCollection requestArgs = new NameValueCollection
-                {
-                    { "RequestMethod", "AddUserData" },
-                    { "UserID", userID.ToString() },
-                    { "LastLocation", SerializeLocation(sceneID, position, lookAt) }
-                };
-
-            OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
-            bool success = response["Success"].AsBoolean();
-
             if (!success)
-                m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
+                m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
 
             return success;
         }
 
+        ///// <summary>
+        ///// Fetch the last known avatar location with GetSession and persist it
+        ///// as user data with AddUserData
+        ///// </summary>
+        //private bool SetLastLocation(UUID sessionID)
+        //{
+        //    NameValueCollection requestArgs = new NameValueCollection
+        //    {
+        //        { "RequestMethod", "GetSession" },
+        //        { "SessionID", sessionID.ToString() }
+        //    };
+
+        //    OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
+        //    bool success = response["Success"].AsBoolean();
+
+        //    if (success)
+        //    {
+        //        UUID userID = response["UserID"].AsUUID();
+        //        UUID sceneID = response["SceneID"].AsUUID();
+        //        Vector3 position = response["ScenePosition"].AsVector3();
+        //        Vector3 lookAt = response["SceneLookAt"].AsVector3();
+
+        //        return SetLastLocation(userID, sceneID, position, lookAt);
+        //    }
+        //    else
+        //    {
+        //        m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
+        //            " while saving last location: " + response["Message"].AsString());
+        //    }
+
+        //    return success;
+        //}
+
         private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
         {
             if (sessionResponse == null)
diff --git a/OpenSim/Services/Interfaces/IGridUserService.cs b/OpenSim/Services/Interfaces/IGridUserService.cs
index e629dff..3d11b3e 100644
--- a/OpenSim/Services/Interfaces/IGridUserService.cs
+++ b/OpenSim/Services/Interfaces/IGridUserService.cs
@@ -108,7 +108,7 @@ namespace OpenSim.Services.Interfaces
         bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
         
         bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt);
-        bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
+        bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
     
         GridUserInfo GetGridUserInfo(string userID);
     }
diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs
index 697ba63..00a1ae2 100644
--- a/OpenSim/Services/UserAccountService/GridUserService.cs
+++ b/OpenSim/Services/UserAccountService/GridUserService.cs
@@ -139,7 +139,7 @@ namespace OpenSim.Services.UserAccountService
             return m_Database.Store(d);
         }
 
-        public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
+        public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
         {
             //m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID);
             GridUserData d = m_Database.Get(userID);
-- 
cgit v1.1