diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | 131 |
1 files changed, 74 insertions, 57 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index b89f753..10b0759 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | |||
@@ -255,7 +255,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
255 | #region Inform Client of Neighbours | 255 | #region Inform Client of Neighbours |
256 | 256 | ||
257 | private delegate void InformClientOfNeighbourDelegate( | 257 | private delegate void InformClientOfNeighbourDelegate( |
258 | ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, IPEndPoint endPoint); | 258 | ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, IPEndPoint endPoint, bool newAgent); |
259 | 259 | ||
260 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) | 260 | private void InformClientOfNeighbourCompleted(IAsyncResult iar) |
261 | { | 261 | { |
@@ -274,8 +274,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
274 | /// <param name="regionHandle"></param> | 274 | /// <param name="regionHandle"></param> |
275 | /// <param name="endPoint"></param> | 275 | /// <param name="endPoint"></param> |
276 | private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, | 276 | private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, |
277 | IPEndPoint endPoint) | 277 | IPEndPoint endPoint, bool newAgent) |
278 | { | 278 | { |
279 | // Let's wait just a little to give time to originating regions to catch up with closing child agents | ||
280 | // after a cross here | ||
281 | Thread.Sleep(200); | ||
282 | |||
279 | uint x, y; | 283 | uint x, y; |
280 | Utils.LongToUInts(reg.RegionHandle, out x, out y); | 284 | Utils.LongToUInts(reg.RegionHandle, out x, out y); |
281 | x = x / Constants.RegionSize; | 285 | x = x / Constants.RegionSize; |
@@ -287,7 +291,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
287 | 291 | ||
288 | bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, a); | 292 | bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, a); |
289 | 293 | ||
290 | if (regionAccepted) | 294 | if (regionAccepted && newAgent) |
291 | { | 295 | { |
292 | IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); | 296 | IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); |
293 | if (eq != null) | 297 | if (eq != null) |
@@ -362,6 +366,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
362 | 366 | ||
363 | /// Collect as many seeds as possible | 367 | /// Collect as many seeds as possible |
364 | Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(avatar.Scene.GetChildrenSeeds(avatar.UUID)); | 368 | Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(avatar.Scene.GetChildrenSeeds(avatar.UUID)); |
369 | //Console.WriteLine(" !!! No. of seeds: " + seeds.Count); | ||
365 | if (!seeds.ContainsKey(avatar.Scene.RegionInfo.RegionHandle)) | 370 | if (!seeds.ContainsKey(avatar.Scene.RegionInfo.RegionHandle)) |
366 | seeds.Add(avatar.Scene.RegionInfo.RegionHandle, avatar.ControllingClient.RequestClientInfo().CapsPath); | 371 | seeds.Add(avatar.Scene.RegionInfo.RegionHandle, avatar.ControllingClient.RequestClientInfo().CapsPath); |
367 | 372 | ||
@@ -369,22 +374,26 @@ namespace OpenSim.Region.Environment.Scenes | |||
369 | List<AgentCircuitData> cagents = new List<AgentCircuitData>(); | 374 | List<AgentCircuitData> cagents = new List<AgentCircuitData>(); |
370 | foreach (SimpleRegionInfo neighbour in neighbours) | 375 | foreach (SimpleRegionInfo neighbour in neighbours) |
371 | { | 376 | { |
372 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | 377 | if (neighbour.RegionHandle != avatar.Scene.RegionInfo.RegionHandle) |
373 | agent.BaseFolder = UUID.Zero; | ||
374 | agent.InventoryFolder = UUID.Zero; | ||
375 | agent.startpos = new Vector3(128, 128, 70); | ||
376 | agent.child = true; | ||
377 | |||
378 | if (newRegions.Contains(neighbour.RegionHandle)) | ||
379 | { | 378 | { |
380 | agent.CapsPath = Util.GetRandomCapsPath(); | ||
381 | avatar.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); | ||
382 | seeds.Add(neighbour.RegionHandle, agent.CapsPath); | ||
383 | } | ||
384 | else | ||
385 | agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, neighbour.RegionHandle); | ||
386 | 379 | ||
387 | cagents.Add(agent); | 380 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); |
381 | agent.BaseFolder = UUID.Zero; | ||
382 | agent.InventoryFolder = UUID.Zero; | ||
383 | agent.startpos = new Vector3(128, 128, 70); | ||
384 | agent.child = true; | ||
385 | |||
386 | if (newRegions.Contains(neighbour.RegionHandle)) | ||
387 | { | ||
388 | agent.CapsPath = Util.GetRandomCapsPath(); | ||
389 | avatar.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); | ||
390 | seeds.Add(neighbour.RegionHandle, agent.CapsPath); | ||
391 | } | ||
392 | else | ||
393 | agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, neighbour.RegionHandle); | ||
394 | |||
395 | cagents.Add(agent); | ||
396 | } | ||
388 | } | 397 | } |
389 | 398 | ||
390 | /// Update all child agent with everyone's seeds | 399 | /// Update all child agent with everyone's seeds |
@@ -398,16 +407,22 @@ namespace OpenSim.Region.Environment.Scenes | |||
398 | //avatar.Scene.DumpChildrenSeeds(avatar.UUID); | 407 | //avatar.Scene.DumpChildrenSeeds(avatar.UUID); |
399 | //avatar.DumpKnownRegions(); | 408 | //avatar.DumpKnownRegions(); |
400 | 409 | ||
410 | bool newAgent = false; | ||
401 | int count = 0; | 411 | int count = 0; |
402 | foreach (SimpleRegionInfo neighbour in neighbours) | 412 | foreach (SimpleRegionInfo neighbour in neighbours) |
403 | { | 413 | { |
404 | // Don't do it if there's already an agent in that region | 414 | // Don't do it if there's already an agent in that region |
405 | if (newRegions.Contains(neighbour.RegionHandle)) | 415 | if (newRegions.Contains(neighbour.RegionHandle)) |
416 | newAgent = true; | ||
417 | else | ||
418 | newAgent = false; | ||
419 | |||
420 | if (neighbour.RegionHandle != avatar.Scene.RegionInfo.RegionHandle) | ||
406 | { | 421 | { |
407 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 422 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; |
408 | try | 423 | try |
409 | { | 424 | { |
410 | d.BeginInvoke(avatar, cagents[count], neighbour, neighbour.ExternalEndPoint, | 425 | d.BeginInvoke(avatar, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, |
411 | InformClientOfNeighbourCompleted, | 426 | InformClientOfNeighbourCompleted, |
412 | d); | 427 | d); |
413 | } | 428 | } |
@@ -429,11 +444,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
429 | 444 | ||
430 | } | 445 | } |
431 | } | 446 | } |
432 | else | ||
433 | m_log.Debug("[SCM]: Skipping common neighbor " + neighbour.RegionLocX + ", " + neighbour.RegionLocY); | ||
434 | |||
435 | count++; | 447 | count++; |
436 | |||
437 | } | 448 | } |
438 | } | 449 | } |
439 | 450 | ||
@@ -450,7 +461,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
450 | agent.child = true; | 461 | agent.child = true; |
451 | 462 | ||
452 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 463 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; |
453 | d.BeginInvoke(avatar, agent, region, region.ExternalEndPoint, | 464 | d.BeginInvoke(avatar, agent, region, region.ExternalEndPoint, true, |
454 | InformClientOfNeighbourCompleted, | 465 | InformClientOfNeighbourCompleted, |
455 | d); | 466 | d); |
456 | } | 467 | } |
@@ -748,6 +759,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
748 | // once we reach here... | 759 | // once we reach here... |
749 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | 760 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); |
750 | 761 | ||
762 | // Let's close some agents | ||
763 | avatar.CloseChildAgents(newRegionX, newRegionY); | ||
764 | |||
765 | string capsPath = String.Empty; | ||
751 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | 766 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); |
752 | agent.BaseFolder = UUID.Zero; | 767 | agent.BaseFolder = UUID.Zero; |
753 | agent.InventoryFolder = UUID.Zero; | 768 | agent.InventoryFolder = UUID.Zero; |
@@ -757,36 +772,37 @@ namespace OpenSim.Region.Environment.Scenes | |||
757 | { | 772 | { |
758 | // brand new agent | 773 | // brand new agent |
759 | agent.CapsPath = Util.GetRandomCapsPath(); | 774 | agent.CapsPath = Util.GetRandomCapsPath(); |
775 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) | ||
776 | { | ||
777 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
778 | return; | ||
779 | } | ||
780 | |||
781 | // TODO Should construct this behind a method | ||
782 | capsPath = | ||
783 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | ||
784 | + "/CAPS/" + agent.CapsPath + "0000/"; | ||
785 | |||
786 | if (eq != null) | ||
787 | { | ||
788 | OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint); | ||
789 | eq.Enqueue(Item, avatar.UUID); | ||
790 | |||
791 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); | ||
792 | eq.Enqueue(Item, avatar.UUID); | ||
793 | } | ||
794 | else | ||
795 | { | ||
796 | avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint); | ||
797 | } | ||
760 | } | 798 | } |
761 | else | 799 | else |
762 | { | 800 | { |
763 | // child agent already there | ||
764 | agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle); | 801 | agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle); |
802 | capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort | ||
803 | + "/CAPS/" + agent.CapsPath + "0000/"; | ||
765 | } | 804 | } |
766 | 805 | ||
767 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) | ||
768 | { | ||
769 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
770 | return; | ||
771 | } | ||
772 | |||
773 | // TODO Should construct this behind a method | ||
774 | string capsPath = | ||
775 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | ||
776 | + "/CAPS/" + agent.CapsPath + "0000/"; | ||
777 | |||
778 | if (eq != null) | ||
779 | { | ||
780 | OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint); | ||
781 | eq.Enqueue(Item, avatar.UUID); | ||
782 | |||
783 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath); | ||
784 | eq.Enqueue(Item, avatar.UUID); | ||
785 | } | ||
786 | else | ||
787 | { | ||
788 | avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint); | ||
789 | } | ||
790 | 806 | ||
791 | if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | 807 | if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, |
792 | position, false)) | 808 | position, false)) |
@@ -826,24 +842,25 @@ namespace OpenSim.Region.Environment.Scenes | |||
826 | } | 842 | } |
827 | 843 | ||
828 | 844 | ||
829 | // Let's close some children agents | ||
830 | avatar.CloseChildAgents(newRegionX, newRegionY); | ||
831 | // Close this ScenePresence too | ||
832 | //avatar.Close(); | ||
833 | |||
834 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 845 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
835 | 846 | ||
836 | //if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 847 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
837 | //{ | 848 | { |
838 | // CloseConnection(avatar.UUID); | 849 | CloseConnection(avatar.UUID); |
839 | //} | 850 | } |
840 | 851 | ||
841 | // if (teleport success) // seems to be always success here | 852 | // if (teleport success) // seems to be always success here |
842 | // the user may change their profile information in other region, | 853 | // the user may change their profile information in other region, |
843 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 854 | // so the userinfo in UserProfileCache is not reliable any more, delete it |
844 | if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) | 855 | if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) |
856 | { | ||
845 | m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); | 857 | m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); |
846 | m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); | 858 | m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); |
859 | } | ||
860 | |||
861 | // Close this ScenePresence too | ||
862 | //avatar.Close(); | ||
863 | |||
847 | } | 864 | } |
848 | else | 865 | else |
849 | { | 866 | { |