From f44c29effbd0d14427f288470aee028e9e09d6e3 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Sun, 19 Oct 2014 15:51:12 +0100
Subject:  try to fix propagation of seeds to all relevante regions

---
 OpenSim/Framework/ChildAgentDataUpdate.cs          |  38 ++++++++
 .../EntityTransfer/EntityTransferModule.cs         | 104 ++++++++++++++++-----
 OpenSim/Region/Framework/Scenes/Scene.cs           |   8 +-
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   |  26 +++---
 4 files changed, 139 insertions(+), 37 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 5078f69..0763bbc 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Framework
         // This probably shouldn't be here
         public byte[] Throttles;
 
+        public Dictionary<ulong, string> ChildrenCapSeeds = null;
 
         public OSDMap Pack()
         {
@@ -119,6 +120,19 @@ namespace OpenSim.Framework
             if ((Throttles != null) && (Throttles.Length > 0))
                 args["throttles"] = OSD.FromBinary(Throttles);
 
+            if (ChildrenCapSeeds != null && ChildrenCapSeeds.Count > 0)
+            {
+                OSDArray childrenSeeds = new OSDArray(ChildrenCapSeeds.Count);
+                foreach (KeyValuePair<ulong, string> kvp in ChildrenCapSeeds)
+                {
+                    OSDMap pair = new OSDMap();
+                    pair["handle"] = OSD.FromString(kvp.Key.ToString());
+                    pair["seed"] = OSD.FromString(kvp.Value);
+                    childrenSeeds.Add(pair);
+                }
+                args["children_seeds"] = childrenSeeds;
+            }
+
             return args;
         }
 
@@ -165,6 +179,30 @@ namespace OpenSim.Framework
 
             if (args["throttles"] != null)
                 Throttles = args["throttles"].AsBinary();
+
+            if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
+                            (args["children_seeds"].Type == OSDType.Array))
+            {
+                OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
+                ChildrenCapSeeds = new Dictionary<ulong, string>();
+                foreach (OSD o in childrenSeeds)
+                {
+                    if (o.Type == OSDType.Map)
+                    {
+                        ulong handle = 0;
+                        string seed = "";
+                        OSDMap pair = (OSDMap)o;
+                        if (pair["handle"] != null)
+                            if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
+                                continue;
+                        if (pair["seed"] != null)
+                            seed = pair["seed"].AsString();
+                        if (!ChildrenCapSeeds.ContainsKey(handle))
+                            ChildrenCapSeeds.Add(handle, seed);
+                    }
+                }
+            }
+
         }
 
         /// <summary>
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ae571c0..87a0ff6 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1838,33 +1838,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
         {
             m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
 
+            ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
+            ulong regionhandler = region.RegionHandle;
+
+            Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
+
+            if (seeds.ContainsKey(regionhandler))
+                seeds.Remove(regionhandler);
+
+            List<ulong> oldregions = new List<ulong>(seeds.Keys);
+
+            if (oldregions.Contains(currentRegionHandler))
+                oldregions.Remove(currentRegionHandler);
+
+            if (!seeds.ContainsKey(currentRegionHandler))
+                seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath);
+
             AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
             AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
             agent.BaseFolder = UUID.Zero;
             agent.InventoryFolder = UUID.Zero;
             agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region);
             agent.child = true;
-
             agent.Appearance = new AvatarAppearance();
             agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
 
             agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
+            seeds.Add(regionhandler, agent.CapsPath);
 
-            agent.ChildrenCapSeeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
-            //m_log.DebugFormat("[XXX] Seeds 1 {0}", agent.ChildrenCapSeeds.Count);
-
-            if (!agent.ChildrenCapSeeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle))
-                agent.ChildrenCapSeeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
-            //m_log.DebugFormat("[XXX] Seeds 2 {0}", agent.ChildrenCapSeeds.Count);
-
-            sp.AddNeighbourRegion(region.RegionHandle, agent.CapsPath);
-            agent.ChildrenCapSeeds.Add(region.RegionHandle, agent.CapsPath);
-
+            agent.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
+            
             if (sp.Scene.CapsModule != null)
             {
-                sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, agent.ChildrenCapSeeds);
+                sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
             }
 
+            sp.KnownRegions = seeds;
+
             if (currentAgentCircuit != null)
             {
                 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -1875,7 +1885,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                 agent.Id0 = currentAgentCircuit.Id0;
             }
 
-            Thread.Sleep(200);  // the original delay that was at InformClientOfNeighbourAsync start
+            AgentPosition agentpos = null;
+
+            if (oldregions.Count > 0)
+            {
+                agentpos = new AgentPosition();
+                agentpos.AgentID = new UUID(sp.UUID.Guid);
+                agentpos.SessionID = sp.ControllingClient.SessionId;
+                agentpos.Size = sp.Appearance.AvatarSize;
+                agentpos.Center = sp.CameraPosition;
+                agentpos.Far = sp.DrawDistance;
+                agentpos.Position = sp.AbsolutePosition;
+                agentpos.Velocity = sp.Velocity;
+                agentpos.RegionHandle = currentRegionHandler;
+                agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
+                agentpos.ChildrenCapSeeds = seeds;
+            }
 
             IPEndPoint external = region.ExternalEndPoint;
             if (external != null)
@@ -1885,7 +1910,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                           InformClientOfNeighbourCompleted,
                           d);
             }
+
+            if(oldregions.Count >0)
+            {
+                uint neighbourx;
+                uint neighboury;
+                UUID scope = sp.Scene.RegionInfo.ScopeID;
+                foreach (ulong handler in oldregions)
+                {
+                    // crap code
+                    Utils.LongToUInts(handler, out neighbourx, out neighboury);
+                    GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury);
+                    sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos);
+                }
+            }
         }
+
         #endregion
 
         #region Enable Child Agents
@@ -1935,7 +1975,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
 
             List<AgentCircuitData> cagents = new List<AgentCircuitData>();
-            List<GridRegion> newneighbours = new List<GridRegion>();
+            List<ulong> newneighbours = new List<ulong>();
 
             ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
 
@@ -1972,7 +2012,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                     agent.Id0 = currentAgentCircuit.Id0;
                 }
 
-                newneighbours.Add(neighbour);
+                newneighbours.Add(handler);
                 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
                 seeds.Add(handler, agent.CapsPath);
                 cagents.Add(agent);
@@ -1993,21 +2033,41 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
 
             sp.KnownRegions = seeds;
-            
-            if (newneighbours.Count > 0)
+
+            AgentPosition agentpos = new AgentPosition();
+            agentpos.AgentID = new UUID(sp.UUID.Guid);
+            agentpos.SessionID = sp.ControllingClient.SessionId;
+            agentpos.Size = sp.Appearance.AvatarSize;
+            agentpos.Center = sp.CameraPosition;
+            agentpos.Far = sp.DrawDistance;
+            agentpos.Position = sp.AbsolutePosition;
+            agentpos.Velocity = sp.Velocity;
+            agentpos.RegionHandle = currentRegionHandler;
+            agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
+            agentpos.ChildrenCapSeeds = seeds;
+
+            if (neighbours.Count - previousRegionNeighbourHandles.Count > 0)
             {
                 Util.FireAndForget(delegate
                 {
                     Thread.Sleep(200);  // the original delay that was at InformClientOfNeighbourAsync start
                     int count = 0;
 
-                    foreach (GridRegion neighbour in newneighbours)
+                    foreach (GridRegion neighbour in neighbours)
                     {
+                        ulong handler = neighbour.RegionHandle;
                         try
                         {
-                            InformClientOfNeighbourAsync(sp, cagents[count], neighbour,
-                                neighbour.ExternalEndPoint, true);
-                            count++;
+                            if (newneighbours.Contains(handler))
+                            {
+                                InformClientOfNeighbourAsync(sp, cagents[count], neighbour,
+                                    neighbour.ExternalEndPoint, true);
+                                count++;
+                            }
+                            else if(!previousRegionNeighbourHandles.Contains(handler))
+                            {
+                                sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos); 
+                            }
                         }
                         catch (ArgumentOutOfRangeException)
                         {
@@ -2483,7 +2543,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             // no one or failed lets go back and tell physics to go on
             oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
             oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
-            oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
+//            oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
 
             grp.AbsolutePosition = oldGroupPosition;
             grp.Velocity = Vector3.Zero;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 829d4ce..4a6f72c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4558,8 +4558,14 @@ namespace OpenSim.Region.Framework.Scenes
             // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
             ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
 
-            if (sp != null)
+            if (sp != null)           
             {
+                if (!sp.IsChildAgent)
+                {
+                    m_log.WarnFormat("[SCENE]: Ignoring a child update on a root agent {0} {1} in {2}",
+                            sp.Name, sp.UUID, Name);
+                    return false;
+                }
                 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
                 {
                     m_log.WarnFormat(
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fbb18b7..405ad73 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1684,20 +1684,6 @@ namespace OpenSim.Region.Framework.Scenes
                         return;
                 }
 
-                // Prevent teleporting to an underground location
-                // (may crash client otherwise)
-                //
-
-/* this is done in MakeRootAgent 
-                Vector3 pos = AbsolutePosition;
-                float ground = m_scene.GetGroundHeight(pos.X, pos.Y);
-                if (pos.Z < ground + 1.5f)
-                {
-                    pos.Z = ground + 1.5f;
-                    AbsolutePosition = pos;
-                }
-*/
-
                 m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
 
                 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
@@ -1904,7 +1890,9 @@ namespace OpenSim.Region.Framework.Scenes
                     {
                         IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
                         if (m_agentTransfer != null)
+                        {
                             m_agentTransfer.EnableChildAgents(this);
+                        }
                     }
                 }
 
@@ -4171,6 +4159,16 @@ namespace OpenSim.Region.Framework.Scenes
             if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0)
                 ControllingClient.SetChildAgentThrottle(cAgentData.Throttles);
 
+            if(cAgentData.ChildrenCapSeeds != null && cAgentData.ChildrenCapSeeds.Count >0)
+            {
+                if (Scene.CapsModule != null)
+                {
+                    Scene.CapsModule.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds);
+                }
+
+                KnownRegions = cAgentData.ChildrenCapSeeds;
+            }
+
             //cAgentData.AVHeight;
             //m_velocity = cAgentData.Velocity;
         }
-- 
cgit v1.1