diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs index 9e23831a45..595ac09dc8 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs @@ -169,6 +169,17 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid // once we reach here... //avatar.Scene.RemoveCapsHandler(avatar.UUID); + // Let's close some agents + if (isHyperLink) // close them all except this one + { + List regions = new List(avatar.KnownChildRegionHandles); + regions.Remove(avatar.Scene.RegionInfo.RegionHandle); + SendCloseChildAgentConnections(avatar.UUID, regions); + } + else // close just a few + avatar.CloseChildAgents(newRegionX, newRegionY); + + string capsPath = String.Empty; AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); agent.BaseFolder = UUID.Zero; agent.InventoryFolder = UUID.Zero; @@ -178,38 +189,39 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid { // brand new agent agent.CapsPath = Util.GetRandomCapsPath(); + if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) + { + avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); + return; + } + + // TODO Should construct this behind a method + capsPath = + "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + agent.CapsPath + "0000/"; + + if (eq != null) + { + OSD Item = EventQueueHelper.EnableSimulator(realHandle, reg.ExternalEndPoint); + eq.Enqueue(Item, avatar.UUID); + + Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); + eq.Enqueue(Item, avatar.UUID); + } + else + { + avatar.ControllingClient.InformClientOfNeighbour(realHandle, reg.ExternalEndPoint); + // TODO: make Event Queue disablable! + } } else { // child agent already there agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle); + capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + agent.CapsPath + "0000/"; } - - if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) - { - avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); - return; - } - - // TODO Should construct this behind a method - string capsPath = - "http://" + reg.ExternalHostName + ":" + reg.HttpPort - + "/CAPS/" + agent.CapsPath + "0000/"; - - if (eq != null) - { - OSD Item = EventQueueHelper.EnableSimulator(realHandle, reg.ExternalEndPoint); - eq.Enqueue(Item, avatar.UUID); - - Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); - eq.Enqueue(Item, avatar.UUID); - } - else - { - avatar.ControllingClient.InformClientOfNeighbour(realHandle, reg.ExternalEndPoint); - // TODO: make Event Queue disablable! - } - + m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, position, false); @@ -258,28 +270,24 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid } - // Let's close some children agents - if (isHyperLink) // close them all - SendCloseChildAgentConnections(avatar.UUID, avatar.KnownChildRegionHandles); - else // close just a few - avatar.CloseChildAgents(newRegionX, newRegionY); - //avatar.Close(); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone /// /// Hypergrid mod: extra check for isHyperLink /// - //if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) - //{ - // CloseConnection(avatar.UUID); - //} + if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) + { + CloseConnection(avatar.UUID); + } // if (teleport success) // seems to be always success here // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) + { m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); - m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); + m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); + } } else { diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 6ce19c6e06..9497043cf8 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -2657,7 +2657,7 @@ namespace OpenSim.Region.Environment.Scenes GetAvatarAppearance(client, out appearance); ScenePresence avatar = m_sceneGraph.CreateAndAddChildScenePresence(client, appearance); - avatar.KnownRegions = GetChildrenSeeds(avatar.UUID); + //avatar.KnownRegions = GetChildrenSeeds(avatar.UUID); return avatar; } @@ -2871,9 +2871,6 @@ namespace OpenSim.Region.Environment.Scenes /// public void NewUserConnection(AgentCircuitData agent) { - m_log.DebugFormat("[CONNECTION DEBUGGING] Adding NewUserConnection for {0} in {1} with CC of {2}", agent.AgentID, - RegionInfo.RegionName, agent.circuitcode); - if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) { m_log.WarnFormat( @@ -2883,9 +2880,19 @@ namespace OpenSim.Region.Environment.Scenes /// Diva: Horrible stuff! capsPaths[agent.AgentID] = agent.CapsPath; - //m_log.DebugFormat("------------>child seeds in {0}: {1}", RegionInfo.RegionName, ((agent.ChildrenCapSeeds == null) ? "null" : agent.ChildrenCapSeeds.Count.ToString())); childrenSeeds[agent.AgentID] = ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds); + ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); + if (sp != null) + { + m_log.DebugFormat("[CONNECTION DEBUGGING]: Updated agent {0} in {1}", agent.AgentID, RegionInfo.RegionName); + sp.AdjustKnownSeeds(); + return; + } + + m_log.DebugFormat("[CONNECTION DEBUGGING]: Adding NewUserConnection for {0} in {1} with CC of {2}", agent.AgentID, + RegionInfo.RegionName, agent.circuitcode); + AddCapsHandler(agent.AgentID); if (!agent.child) diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index b89f753525..10b0759430 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -255,7 +255,7 @@ namespace OpenSim.Region.Environment.Scenes #region Inform Client of Neighbours private delegate void InformClientOfNeighbourDelegate( - ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, IPEndPoint endPoint); + ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, IPEndPoint endPoint, bool newAgent); private void InformClientOfNeighbourCompleted(IAsyncResult iar) { @@ -274,8 +274,12 @@ namespace OpenSim.Region.Environment.Scenes /// /// private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, - IPEndPoint endPoint) + IPEndPoint endPoint, bool newAgent) { + // Let's wait just a little to give time to originating regions to catch up with closing child agents + // after a cross here + Thread.Sleep(200); + uint x, y; Utils.LongToUInts(reg.RegionHandle, out x, out y); x = x / Constants.RegionSize; @@ -287,7 +291,7 @@ namespace OpenSim.Region.Environment.Scenes bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, a); - if (regionAccepted) + if (regionAccepted && newAgent) { IEventQueue eq = avatar.Scene.RequestModuleInterface(); if (eq != null) @@ -362,6 +366,7 @@ namespace OpenSim.Region.Environment.Scenes /// Collect as many seeds as possible Dictionary seeds = new Dictionary(avatar.Scene.GetChildrenSeeds(avatar.UUID)); + //Console.WriteLine(" !!! No. of seeds: " + seeds.Count); if (!seeds.ContainsKey(avatar.Scene.RegionInfo.RegionHandle)) seeds.Add(avatar.Scene.RegionInfo.RegionHandle, avatar.ControllingClient.RequestClientInfo().CapsPath); @@ -369,22 +374,26 @@ namespace OpenSim.Region.Environment.Scenes List cagents = new List(); foreach (SimpleRegionInfo neighbour in neighbours) { - AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = new Vector3(128, 128, 70); - agent.child = true; - - if (newRegions.Contains(neighbour.RegionHandle)) + if (neighbour.RegionHandle != avatar.Scene.RegionInfo.RegionHandle) { - agent.CapsPath = Util.GetRandomCapsPath(); - avatar.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); - seeds.Add(neighbour.RegionHandle, agent.CapsPath); - } - else - agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, neighbour.RegionHandle); - cagents.Add(agent); + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = new Vector3(128, 128, 70); + agent.child = true; + + if (newRegions.Contains(neighbour.RegionHandle)) + { + agent.CapsPath = Util.GetRandomCapsPath(); + avatar.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); + seeds.Add(neighbour.RegionHandle, agent.CapsPath); + } + else + agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, neighbour.RegionHandle); + + cagents.Add(agent); + } } /// Update all child agent with everyone's seeds @@ -398,16 +407,22 @@ namespace OpenSim.Region.Environment.Scenes //avatar.Scene.DumpChildrenSeeds(avatar.UUID); //avatar.DumpKnownRegions(); + bool newAgent = false; int count = 0; foreach (SimpleRegionInfo neighbour in neighbours) { // Don't do it if there's already an agent in that region if (newRegions.Contains(neighbour.RegionHandle)) + newAgent = true; + else + newAgent = false; + + if (neighbour.RegionHandle != avatar.Scene.RegionInfo.RegionHandle) { InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; try { - d.BeginInvoke(avatar, cagents[count], neighbour, neighbour.ExternalEndPoint, + d.BeginInvoke(avatar, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, InformClientOfNeighbourCompleted, d); } @@ -429,11 +444,7 @@ namespace OpenSim.Region.Environment.Scenes } } - else - m_log.Debug("[SCM]: Skipping common neighbor " + neighbour.RegionLocX + ", " + neighbour.RegionLocY); - count++; - } } @@ -450,7 +461,7 @@ namespace OpenSim.Region.Environment.Scenes agent.child = true; InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; - d.BeginInvoke(avatar, agent, region, region.ExternalEndPoint, + d.BeginInvoke(avatar, agent, region, region.ExternalEndPoint, true, InformClientOfNeighbourCompleted, d); } @@ -748,6 +759,10 @@ namespace OpenSim.Region.Environment.Scenes // once we reach here... //avatar.Scene.RemoveCapsHandler(avatar.UUID); + // Let's close some agents + avatar.CloseChildAgents(newRegionX, newRegionY); + + string capsPath = String.Empty; AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); agent.BaseFolder = UUID.Zero; agent.InventoryFolder = UUID.Zero; @@ -757,36 +772,37 @@ namespace OpenSim.Region.Environment.Scenes { // brand new agent agent.CapsPath = Util.GetRandomCapsPath(); + if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) + { + avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); + return; + } + + // TODO Should construct this behind a method + capsPath = + "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + agent.CapsPath + "0000/"; + + if (eq != null) + { + OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint); + eq.Enqueue(Item, avatar.UUID); + + Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); + eq.Enqueue(Item, avatar.UUID); + } + else + { + avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint); + } } else { - // child agent already there agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle); + capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + agent.CapsPath + "0000/"; } - if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) - { - avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); - return; - } - - // TODO Should construct this behind a method - string capsPath = - "http://" + reg.ExternalHostName + ":" + reg.HttpPort - + "/CAPS/" + agent.CapsPath + "0000/"; - - if (eq != null) - { - OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint); - eq.Enqueue(Item, avatar.UUID); - - Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); - eq.Enqueue(Item, avatar.UUID); - } - else - { - avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint); - } if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, position, false)) @@ -826,24 +842,25 @@ namespace OpenSim.Region.Environment.Scenes } - // Let's close some children agents - avatar.CloseChildAgents(newRegionX, newRegionY); - // Close this ScenePresence too - //avatar.Close(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - //if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) - //{ - // CloseConnection(avatar.UUID); - //} + if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + CloseConnection(avatar.UUID); + } // if (teleport success) // seems to be always success here // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) + { m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); - m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); + m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); + } + + // Close this ScenePresence too + //avatar.Close(); + } else { diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index f139ba5342..4668dae88f 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -505,6 +505,28 @@ namespace OpenSim.Region.Environment.Scenes } } + public void AdjustKnownSeeds() + { + Dictionary seeds = Scene.GetChildrenSeeds(UUID); + List old = new List(); + foreach (ulong handle in seeds.Keys) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) + { + old.Add(handle); + } + } + DropOldNeighbours(old); + Scene.SetChildrenSeed(UUID, seeds); + KnownRegions = seeds; + //Console.WriteLine(" ++++++++++AFTER+++++++++++++ "); + //DumpKnownRegions(); + } + public void DumpKnownRegions() { Console.WriteLine("================ KnownRegions {0} ================", Scene.RegionInfo.RegionName); @@ -545,6 +567,7 @@ namespace OpenSim.Region.Environment.Scenes m_grouptitle = gm.GetGroupTitle(m_uuid); AbsolutePosition = m_controllingClient.StartPos; + AdjustKnownSeeds(); TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... @@ -935,7 +958,7 @@ namespace OpenSim.Region.Environment.Scenes if (m_knownChildRegions.ContainsKey(regionHandle)) { m_knownChildRegions.Remove(regionHandle); - //Console.WriteLine(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); + //Console.WriteLine(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); } } } @@ -1949,9 +1972,6 @@ namespace OpenSim.Region.Environment.Scenes CheckForBorderCrossing(); CheckForSignificantMovement(); // sends update to the modules. } - - //if ((x++ % 30) == 0) - // Console.WriteLine(" >> In {0} known regions: {0}, seeds:{1}", Scene.RegionInfo.RegionName, KnownRegions.Count, Scene.GetChildrenSeeds(UUID)); } #endregion @@ -2412,6 +2432,9 @@ namespace OpenSim.Region.Environment.Scenes m_physicsActor.Flying); if (crossingSuccessful) { + // Next, let's close the child agent connections that are too far away. + CloseChildAgents(neighbourx, neighboury); + AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); //Console.WriteLine("BEFORE CROSS"); @@ -2446,15 +2469,15 @@ namespace OpenSim.Region.Environment.Scenes CrossAttachmentsIntoNewRegion(neighbourHandle, true); // m_scene.SendKillObject(m_localId); - // Next, let's close the child agent connections that are too far away. - CloseChildAgents(neighbourx, neighboury); m_scene.NotifyMyCoarseLocationChange(); // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (m_scene.NeedSceneCacheClear(UUID)) + { m_scene.CommsManager.UserProfileCacheService.RemoveUser(UUID); - m_log.InfoFormat("[AVATAR]: User {0} is going to another region, profile cache removed", UUID); + m_log.InfoFormat("[AVATAR]: User {0} is going to another region, profile cache removed", UUID); + } } else { @@ -2487,16 +2510,20 @@ namespace OpenSim.Region.Environment.Scenes { foreach (ulong handle in m_knownChildRegions.Keys) { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - - //Console.WriteLine("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //Console.WriteLine("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); - if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) + // Don't close the agent on this region yet + if (handle != Scene.RegionInfo.RegionHandle) { - byebyeRegions.Add(handle); + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + + //Console.WriteLine("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); + //Console.WriteLine("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); + if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) + { + byebyeRegions.Add(handle); + } } } } @@ -2510,7 +2537,6 @@ namespace OpenSim.Region.Environment.Scenes RemoveNeighbourRegion(handle); } - } #endregion