aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
diff options
context:
space:
mode:
authordiva2008-12-15 16:23:34 +0000
committerdiva2008-12-15 16:23:34 +0000
commit4b71b88114c6ac149571512c57ea005d85147f54 (patch)
tree18b638632d5a85b1670c9e1832398fa2d0dfb6e7 /OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
parentUpdate svn properties. (diff)
downloadopensim-SC_OLD-4b71b88114c6ac149571512c57ea005d85147f54.zip
opensim-SC_OLD-4b71b88114c6ac149571512c57ea005d85147f54.tar.gz
opensim-SC_OLD-4b71b88114c6ac149571512c57ea005d85147f54.tar.bz2
opensim-SC_OLD-4b71b88114c6ac149571512c57ea005d85147f54.tar.xz
Bug fix in new child agents management. Thanks DigiDaz for helping identify this issue.
We need to update all child agents whenever the root agent crosses regions. The update now includes child agents in common neighbours. This is so that those get updated with the seeds of the new child agents that are spawned from the receiving region. This also fixes some timing issues. We need to close child agents from the originating region before we update child agents in the receiving region.
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs131
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 {