aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-05-24 22:26:02 +0100
committerJustin Clark-Casey (justincc)2012-05-24 22:26:02 +0100
commit5c9086ade688b457e9aa9cd0d2099985b7336b71 (patch)
tree06c20284873e91ed30cda64a6d2dd8c9cbf720ce /OpenSim/Region
parentadding status codes from rfc 6585 (diff)
downloadopensim-SC-5c9086ade688b457e9aa9cd0d2099985b7336b71.zip
opensim-SC-5c9086ade688b457e9aa9cd0d2099985b7336b71.tar.gz
opensim-SC-5c9086ade688b457e9aa9cd0d2099985b7336b71.tar.bz2
opensim-SC-5c9086ade688b457e9aa9cd0d2099985b7336b71.tar.xz
Fix issue where a dns resolution failure on the final destination might leave the user unable to teleport since the transit flag was not being reset.
This moves the 'already in transit' check further up and resets the flag if dns resolution fails and in the new required places.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs392
1 files changed, 200 insertions, 192 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 408d63d..4988e93 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -358,33 +358,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
358 ScenePresence sp, GridRegion reg, GridRegion finalDestination, 358 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
359 Vector3 position, Vector3 lookAt, uint teleportFlags) 359 Vector3 position, Vector3 lookAt, uint teleportFlags)
360 { 360 {
361 RegionInfo sourceRegion = sp.Scene.RegionInfo; 361 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
362 362 // of whether the destination region completes the teleport.
363 if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) 363 if (!SetInTransit(sp.UUID))
364 { 364 {
365 sp.ControllingClient.SendTeleportFailed( 365 m_log.DebugFormat(
366 string.Format( 366 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
367 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", 367 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
368 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
369 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
370 MaxTransferDistance));
371 368
372 return; 369 return;
373 } 370 }
374 371
375 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
376
377 if (reg == null || finalDestination == null) 372 if (reg == null || finalDestination == null)
378 { 373 {
379 sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); 374 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
380 return; 375 ResetFromTransit(sp.UUID);
381 }
382
383 if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
384 {
385 m_log.DebugFormat(
386 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
387 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
388 376
389 return; 377 return;
390 } 378 }
@@ -394,6 +382,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
394 sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, 382 sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName,
395 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); 383 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
396 384
385 RegionInfo sourceRegion = sp.Scene.RegionInfo;
386
387 if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination))
388 {
389 sp.ControllingClient.SendTeleportFailed(
390 string.Format(
391 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
392 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
393 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
394 MaxTransferDistance));
395
396 ResetFromTransit(sp.UUID);
397
398 return;
399 }
400
401 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
402
397 uint newRegionX = (uint)(reg.RegionHandle >> 40); 403 uint newRegionX = (uint)(reg.RegionHandle >> 40);
398 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); 404 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
399 uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); 405 uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40);
@@ -405,17 +411,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
405 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 411 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
406 // it's actually doing a lot of work. 412 // it's actually doing a lot of work.
407 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 413 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
408 if (endPoint.Address != null) 414
415 if (endPoint.Address == null)
409 { 416 {
410 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 417 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
411 // both regions 418 ResetFromTransit(sp.UUID);
412 if (sp.ParentID != (uint)0) 419
413 sp.StandUp(); 420 return;
421 }
414 422
415 if (!sp.ValidateAttachments()) 423 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
416 m_log.DebugFormat( 424 // both regions
417 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 425 if (sp.ParentID != (uint)0)
418 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 426 sp.StandUp();
427
428 if (!sp.ValidateAttachments())
429 m_log.DebugFormat(
430 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
431 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
419 432
420// if (!sp.ValidateAttachments()) 433// if (!sp.ValidateAttachments())
421// { 434// {
@@ -423,211 +436,206 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
423// return; 436// return;
424// } 437// }
425 438
426 string reason; 439 string reason;
427 string version; 440 string version;
428 if (!m_scene.SimulationService.QueryAccess( 441 if (!m_scene.SimulationService.QueryAccess(
429 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) 442 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
430 { 443 {
431 sp.ControllingClient.SendTeleportFailed(reason); 444 sp.ControllingClient.SendTeleportFailed(reason);
432 ResetFromTransit(sp.UUID); 445 ResetFromTransit(sp.UUID);
433 446
434 m_log.DebugFormat( 447 m_log.DebugFormat(
435 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 448 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
436 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 449 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
437 450
438 return; 451 return;
439 } 452 }
440 453
441 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 454 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
442 455
443 sp.ControllingClient.SendTeleportStart(teleportFlags); 456 sp.ControllingClient.SendTeleportStart(teleportFlags);
444 457
445 // the avatar.Close below will clear the child region list. We need this below for (possibly) 458 // the avatar.Close below will clear the child region list. We need this below for (possibly)
446 // closing the child agents, so save it here (we need a copy as it is Clear()-ed). 459 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
447 //List<ulong> childRegions = avatar.KnownRegionHandles; 460 //List<ulong> childRegions = avatar.KnownRegionHandles;
448 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport 461 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
449 // failure at this point (unlike a border crossing failure). So perhaps this can never fail 462 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
450 // once we reach here... 463 // once we reach here...
451 //avatar.Scene.RemoveCapsHandler(avatar.UUID); 464 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
452 465
453 string capsPath = String.Empty; 466 string capsPath = String.Empty;
454 467
455 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 468 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
456 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); 469 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
457 agentCircuit.startpos = position; 470 agentCircuit.startpos = position;
458 agentCircuit.child = true; 471 agentCircuit.child = true;
459 agentCircuit.Appearance = sp.Appearance; 472 agentCircuit.Appearance = sp.Appearance;
460 if (currentAgentCircuit != null) 473 if (currentAgentCircuit != null)
461 { 474 {
462 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; 475 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
463 agentCircuit.IPAddress = currentAgentCircuit.IPAddress; 476 agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
464 agentCircuit.Viewer = currentAgentCircuit.Viewer; 477 agentCircuit.Viewer = currentAgentCircuit.Viewer;
465 agentCircuit.Channel = currentAgentCircuit.Channel; 478 agentCircuit.Channel = currentAgentCircuit.Channel;
466 agentCircuit.Mac = currentAgentCircuit.Mac; 479 agentCircuit.Mac = currentAgentCircuit.Mac;
467 agentCircuit.Id0 = currentAgentCircuit.Id0; 480 agentCircuit.Id0 = currentAgentCircuit.Id0;
468 } 481 }
469 482
470 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 483 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
471 { 484 {
472 // brand new agent, let's create a new caps seed 485 // brand new agent, let's create a new caps seed
473 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 486 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
474 } 487 }
475 488
476 // Let's create an agent there if one doesn't exist yet. 489 // Let's create an agent there if one doesn't exist yet.
477 bool logout = false; 490 bool logout = false;
478 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 491 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
479 { 492 {
480 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); 493 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
481 ResetFromTransit(sp.UUID); 494 ResetFromTransit(sp.UUID);
482 495
483 m_log.DebugFormat( 496 m_log.DebugFormat(
484 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", 497 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
485 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 498 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
486 499
487 return; 500 return;
488 } 501 }
489 502
490 // OK, it got this agent. Let's close some child agents 503 // OK, it got this agent. Let's close some child agents
491 sp.CloseChildAgents(newRegionX, newRegionY); 504 sp.CloseChildAgents(newRegionX, newRegionY);
492 505
493 IClientIPEndpoint ipepClient; 506 IClientIPEndpoint ipepClient;
494 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 507 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
508 {
509 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
510 #region IP Translation for NAT
511 // Uses ipepClient above
512 if (sp.ClientView.TryGet(out ipepClient))
495 { 513 {
496 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 514 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
497 #region IP Translation for NAT 515 }
498 // Uses ipepClient above 516 #endregion
499 if (sp.ClientView.TryGet(out ipepClient)) 517 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
500 {
501 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
502 }
503 #endregion
504 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
505 518
506 if (eq != null) 519 if (eq != null)
507 { 520 {
508 eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); 521 eq.EnableSimulator(destinationHandle, endPoint, sp.UUID);
509 522
510 // ES makes the client send a UseCircuitCode message to the destination, 523 // ES makes the client send a UseCircuitCode message to the destination,
511 // which triggers a bunch of things there. 524 // which triggers a bunch of things there.
512 // So let's wait 525 // So let's wait
513 Thread.Sleep(200); 526 Thread.Sleep(200);
514 527
515 eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 528 eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
516 529
517 }
518 else
519 {
520 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
521 }
522 } 530 }
523 else 531 else
524 { 532 {
525 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); 533 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
526 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
527 } 534 }
535 }
536 else
537 {
538 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
539 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
540 }
528 541
529 // Let's send a full update of the agent. This is a synchronous call. 542 // Let's send a full update of the agent. This is a synchronous call.
530 AgentData agent = new AgentData(); 543 AgentData agent = new AgentData();
531 sp.CopyTo(agent); 544 sp.CopyTo(agent);
532 agent.Position = position; 545 agent.Position = position;
533 SetCallbackURL(agent, sp.Scene.RegionInfo); 546 SetCallbackURL(agent, sp.Scene.RegionInfo);
534 547
535 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 548 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
536 549
537 if (!UpdateAgent(reg, finalDestination, agent)) 550 if (!UpdateAgent(reg, finalDestination, agent))
538 { 551 {
539 // Region doesn't take it 552 // Region doesn't take it
540 m_log.WarnFormat( 553 m_log.WarnFormat(
541 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", 554 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.",
542 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 555 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
543 556
544 Fail(sp, finalDestination, logout); 557 Fail(sp, finalDestination, logout);
545 return; 558 return;
546 } 559 }
547 560
548 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 561 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest");
549 562
550 m_log.DebugFormat( 563 m_log.DebugFormat(
551 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 564 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
552 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 565 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
553 566
554 if (eq != null) 567 if (eq != null)
555 { 568 {
556 eq.TeleportFinishEvent(destinationHandle, 13, endPoint, 569 eq.TeleportFinishEvent(destinationHandle, 13, endPoint,
557 0, teleportFlags, capsPath, sp.UUID); 570 0, teleportFlags, capsPath, sp.UUID);
558 } 571 }
559 else 572 else
560 { 573 {
561 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, 574 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
562 teleportFlags, capsPath); 575 teleportFlags, capsPath);
563 } 576 }
564 577
565 // Let's set this to true tentatively. This does not trigger OnChildAgent 578 // Let's set this to true tentatively. This does not trigger OnChildAgent
566 sp.IsChildAgent = true; 579 sp.IsChildAgent = true;
567 580
568 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which 581 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
569 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation 582 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
570 // that the client contacted the destination before we close things here. 583 // that the client contacted the destination before we close things here.
571 if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) 584 if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID))
572 { 585 {
573 m_log.WarnFormat( 586 m_log.WarnFormat(
574 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 587 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
575 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 588 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
576 589
577 Fail(sp, finalDestination, logout); 590 Fail(sp, finalDestination, logout);
578 return; 591 return;
579 } 592 }
580 593
581 // For backwards compatibility 594 // For backwards compatibility
582 if (version == "Unknown" || version == string.Empty) 595 if (version == "Unknown" || version == string.Empty)
583 { 596 {
584 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it 597 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
585 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); 598 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one...");
586 CrossAttachmentsIntoNewRegion(finalDestination, sp, true); 599 CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
587 } 600 }
588 601
589 // May need to logout or other cleanup 602 // May need to logout or other cleanup
590 AgentHasMovedAway(sp, logout); 603 AgentHasMovedAway(sp, logout);
591 604
592 // Well, this is it. The agent is over there. 605 // Well, this is it. The agent is over there.
593 KillEntity(sp.Scene, sp.LocalId); 606 KillEntity(sp.Scene, sp.LocalId);
594 607
595 // Now let's make it officially a child agent 608 // Now let's make it officially a child agent
596 sp.MakeChildAgent(); 609 sp.MakeChildAgent();
597 610
598// sp.Scene.CleanDroppedAttachments(); 611// sp.Scene.CleanDroppedAttachments();
599 612
600 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 613 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
601
602 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
603 {
604 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
605 // they regard the new region as the current region after receiving the AgentMovementComplete
606 // response. If close is sent before then, it will cause the viewer to quit instead.
607 // However, if this delay is longer, then a viewer can teleport back to this region and experience
608 // a failure because the old ScenePresence has not yet been cleaned up.
609 Thread.Sleep(2000);
610
611 sp.Close();
612 sp.Scene.IncomingCloseAgent(sp.UUID);
613 }
614 else
615 {
616 // now we have a child agent in this region.
617 sp.Reset();
618 }
619 614
620 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 615 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
621 if (sp.Scene.NeedSceneCacheClear(sp.UUID)) 616 {
622 { 617 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
623 m_log.DebugFormat( 618 // they regard the new region as the current region after receiving the AgentMovementComplete
624 "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", 619 // response. If close is sent before then, it will cause the viewer to quit instead.
625 sp.UUID); 620 // However, if this delay is longer, then a viewer can teleport back to this region and experience
626 } 621 // a failure because the old ScenePresence has not yet been cleaned up.
622 Thread.Sleep(2000);
623
624 sp.Close();
625 sp.Scene.IncomingCloseAgent(sp.UUID);
627 } 626 }
628 else 627 else
629 { 628 {
630 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 629 // now we have a child agent in this region.
630 sp.Reset();
631 }
632
633 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
634 if (sp.Scene.NeedSceneCacheClear(sp.UUID))
635 {
636 m_log.DebugFormat(
637 "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
638 sp.UUID);
631 } 639 }
632 } 640 }
633 641