diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 5078f69729..0763bbc49b 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 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 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(); + 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); + } + } + } + } /// diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ae571c01db..87a0ff6b15 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 seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); + + if (seeds.ContainsKey(regionhandler)) + seeds.Remove(regionhandler); + + List oldregions = new List(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(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(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 cagents = new List(); - List newneighbours = new List(); + List newneighbours = new List(); 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(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f); oldGroupPosition.Y = Util.Clamp(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f); - oldGroupPosition.Z = Util.Clamp(oldGroupPosition.Z, 0.5f, 4096.0f); +// oldGroupPosition.Z = Util.Clamp(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 829d4cede3..4a6f72cdaa 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 fbb18b79b2..405ad7386f 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(); 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; }