diff options
author | Melanie | 2013-03-23 11:31:34 +0100 |
---|---|---|
committer | Melanie | 2013-03-23 11:31:34 +0100 |
commit | 8bc43ea773f6a56d34222f03c6ad7645b59347bf (patch) | |
tree | 4426b54b77a53014c7e90019124f26e338e40d26 /OpenSim/Region/CoreModules | |
parent | Fix SceneManager to use the new automatic property throughout. (diff) | |
parent | Merge branch 'avination' into careminster (diff) | |
download | opensim-SC-8bc43ea773f6a56d34222f03c6ad7645b59347bf.zip opensim-SC-8bc43ea773f6a56d34222f03c6ad7645b59347bf.tar.gz opensim-SC-8bc43ea773f6a56d34222f03c6ad7645b59347bf.tar.bz2 opensim-SC-8bc43ea773f6a56d34222f03c6ad7645b59347bf.tar.xz |
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
Diffstat (limited to 'OpenSim/Region/CoreModules')
8 files changed, 138 insertions, 41 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 96e8f35..08e7cb7 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -369,8 +369,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
369 | AssetBase asset = null; | 369 | AssetBase asset = null; |
370 | 370 | ||
371 | string filename = GetFileName(id); | 371 | string filename = GetFileName(id); |
372 | 372 | while (File.Exists(filename)) | |
373 | if (File.Exists(filename)) | ||
374 | { | 373 | { |
375 | FileStream stream = null; | 374 | FileStream stream = null; |
376 | try | 375 | try |
@@ -381,6 +380,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
381 | asset = (AssetBase)bformatter.Deserialize(stream); | 380 | asset = (AssetBase)bformatter.Deserialize(stream); |
382 | 381 | ||
383 | m_DiskHits++; | 382 | m_DiskHits++; |
383 | |||
384 | break; | ||
384 | } | 385 | } |
385 | catch (System.Runtime.Serialization.SerializationException e) | 386 | catch (System.Runtime.Serialization.SerializationException e) |
386 | { | 387 | { |
@@ -393,12 +394,24 @@ namespace OpenSim.Region.CoreModules.Asset | |||
393 | // {different version of AssetBase} -- we should attempt to | 394 | // {different version of AssetBase} -- we should attempt to |
394 | // delete it and re-cache | 395 | // delete it and re-cache |
395 | File.Delete(filename); | 396 | File.Delete(filename); |
397 | |||
398 | break; | ||
399 | } | ||
400 | catch (IOException e) | ||
401 | { | ||
402 | // This is a sharing violation: File exists but can't be opened because it's | ||
403 | // being written | ||
404 | Thread.Sleep(100); | ||
405 | |||
406 | continue; | ||
396 | } | 407 | } |
397 | catch (Exception e) | 408 | catch (Exception e) |
398 | { | 409 | { |
399 | m_log.WarnFormat( | 410 | m_log.WarnFormat( |
400 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", | 411 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", |
401 | filename, id, e.Message, e.StackTrace); | 412 | filename, id, e.Message, e.StackTrace); |
413 | |||
414 | break; | ||
402 | } | 415 | } |
403 | finally | 416 | finally |
404 | { | 417 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index c94d152..f62512e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -573,8 +573,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
573 | } | 573 | } |
574 | 574 | ||
575 | // m_log.DebugFormat( | 575 | // m_log.DebugFormat( |
576 | // "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}", | 576 | // "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", |
577 | // so.Name, so.LocalId, sp.Name, m_scene.Name); | 577 | // so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); |
578 | 578 | ||
579 | // Scripts MUST be snapshotted before the object is | 579 | // Scripts MUST be snapshotted before the object is |
580 | // removed from the scene because doing otherwise will | 580 | // removed from the scene because doing otherwise will |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index dee8ce3..a8fe045 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -829,7 +829,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
829 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | 829 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); |
830 | 830 | ||
831 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | 831 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); |
832 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); | 832 | |
833 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | ||
834 | TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); | ||
835 | List<TestClient> destinationTestClients = new List<TestClient>(); | ||
836 | EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); | ||
837 | |||
838 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); | ||
833 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | 839 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); |
834 | 840 | ||
835 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | 841 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); |
@@ -848,7 +854,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
848 | teleportLookAt, | 854 | teleportLookAt, |
849 | (uint)TeleportFlags.ViaLocation); | 855 | (uint)TeleportFlags.ViaLocation); |
850 | 856 | ||
851 | ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); | 857 | destinationTestClients[0].CompleteMovement(); |
852 | 858 | ||
853 | // Check attachments have made it into sceneB | 859 | // Check attachments have made it into sceneB |
854 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); | 860 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 864f33e..51fe1ea 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -361,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
361 | 361 | ||
362 | public void QueueAppearanceSave(UUID agentid) | 362 | public void QueueAppearanceSave(UUID agentid) |
363 | { | 363 | { |
364 | // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); | 364 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); |
365 | 365 | ||
366 | // 10000 ticks per millisecond, 1000 milliseconds per second | 366 | // 10000 ticks per millisecond, 1000 milliseconds per second |
367 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); | 367 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); |
@@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
658 | return; | 658 | return; |
659 | } | 659 | } |
660 | 660 | ||
661 | // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); | 661 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); |
662 | 662 | ||
663 | // This could take awhile since it needs to pull inventory | 663 | // This could take awhile since it needs to pull inventory |
664 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape | 664 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape |
@@ -667,6 +667,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
667 | // multiple save requests. | 667 | // multiple save requests. |
668 | SetAppearanceAssets(sp.UUID, sp.Appearance); | 668 | SetAppearanceAssets(sp.UUID, sp.Appearance); |
669 | 669 | ||
670 | // List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | ||
671 | // foreach (AvatarAttachment att in attachments) | ||
672 | // { | ||
673 | // m_log.DebugFormat( | ||
674 | // "[AVFACTORY]: For {0} saving attachment {1} at point {2}", | ||
675 | // sp.Name, att.ItemID, att.AttachPoint); | ||
676 | // } | ||
677 | |||
670 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | 678 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); |
671 | 679 | ||
672 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. | 680 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 4c3f1cc..174642d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -256,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
256 | // If camera is moved into client, then camera position can be used | 256 | // If camera is moved into client, then camera position can be used |
257 | // MT: No, it can't, as chat is heard from the avatar position, not | 257 | // MT: No, it can't, as chat is heard from the avatar position, not |
258 | // the camera position. | 258 | // the camera position. |
259 | s.ForEachRootScenePresence( | 259 | s.ForEachScenePresence( |
260 | delegate(ScenePresence presence) | 260 | delegate(ScenePresence presence) |
261 | { | 261 | { |
262 | if (destination != UUID.Zero && presence.UUID != destination) | 262 | if (destination != UUID.Zero && presence.UUID != destination) |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b2c9564..25334b9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -167,6 +167,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
167 | 167 | ||
168 | if (!DisableInterRegionTeleportCancellation) | 168 | if (!DisableInterRegionTeleportCancellation) |
169 | client.OnTeleportCancel += OnClientCancelTeleport; | 169 | client.OnTeleportCancel += OnClientCancelTeleport; |
170 | |||
171 | client.OnConnectionClosed += OnConnectionClosed; | ||
170 | } | 172 | } |
171 | 173 | ||
172 | public virtual void Close() {} | 174 | public virtual void Close() {} |
@@ -185,6 +187,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
185 | 187 | ||
186 | #region Agent Teleports | 188 | #region Agent Teleports |
187 | 189 | ||
190 | private void OnConnectionClosed(IClientAPI client) | ||
191 | { | ||
192 | if (client.IsLoggingOut) | ||
193 | { | ||
194 | m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting); | ||
195 | |||
196 | m_log.DebugFormat( | ||
197 | "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", | ||
198 | client.Name, Scene.Name); | ||
199 | } | ||
200 | } | ||
201 | |||
188 | private void OnClientCancelTeleport(IClientAPI client) | 202 | private void OnClientCancelTeleport(IClientAPI client) |
189 | { | 203 | { |
190 | m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); | 204 | m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling); |
@@ -520,12 +534,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
520 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | 534 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", |
521 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | 535 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); |
522 | 536 | ||
523 | // if (!sp.ValidateAttachments()) | ||
524 | // { | ||
525 | // sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | ||
526 | // return; | ||
527 | // } | ||
528 | |||
529 | string reason; | 537 | string reason; |
530 | string version; | 538 | string version; |
531 | if (!Scene.SimulationService.QueryAccess( | 539 | if (!Scene.SimulationService.QueryAccess( |
@@ -588,6 +596,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
588 | } | 596 | } |
589 | 597 | ||
590 | // Let's create an agent there if one doesn't exist yet. | 598 | // Let's create an agent there if one doesn't exist yet. |
599 | // NOTE: logout will always be false for a non-HG teleport. | ||
591 | bool logout = false; | 600 | bool logout = false; |
592 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 601 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) |
593 | { | 602 | { |
@@ -608,6 +617,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
608 | 617 | ||
609 | return; | 618 | return; |
610 | } | 619 | } |
620 | else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
621 | { | ||
622 | m_log.DebugFormat( | ||
623 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", | ||
624 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
625 | |||
626 | return; | ||
627 | } | ||
611 | 628 | ||
612 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. | 629 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. |
613 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 630 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
@@ -630,11 +647,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
630 | 647 | ||
631 | if (m_eqModule != null) | 648 | if (m_eqModule != null) |
632 | { | 649 | { |
650 | // The EnableSimulator message makes the client establish a connection with the destination | ||
651 | // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the | ||
652 | // correct circuit code. | ||
633 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); | 653 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); |
634 | 654 | ||
635 | // ES makes the client send a UseCircuitCode message to the destination, | 655 | // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination |
636 | // which triggers a bunch of things there. | 656 | // simulator to confirm that it has established communication with the viewer. |
637 | // So let's wait | ||
638 | Thread.Sleep(200); | 657 | Thread.Sleep(200); |
639 | 658 | ||
640 | // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears | 659 | // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears |
@@ -645,6 +664,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
645 | } | 664 | } |
646 | else | 665 | else |
647 | { | 666 | { |
667 | // XXX: This is a little misleading since we're information the client of its avatar destination, | ||
668 | // which may or may not be a neighbour region of the source region. This path is probably little | ||
669 | // used anyway (with EQ being the one used). But it is currently being used for test code. | ||
648 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | 670 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); |
649 | } | 671 | } |
650 | } | 672 | } |
@@ -662,14 +684,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
662 | 684 | ||
663 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | 685 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); |
664 | 686 | ||
687 | // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to | ||
688 | // establish th econnection to the destination which makes it return true. | ||
689 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
690 | { | ||
691 | m_log.DebugFormat( | ||
692 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", | ||
693 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
694 | |||
695 | return; | ||
696 | } | ||
697 | |||
698 | // A common teleport failure occurs when we can send CreateAgent to the | ||
699 | // destination region but the viewer cannot establish the connection (e.g. due to network issues between | ||
700 | // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then | ||
701 | // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). | ||
665 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | 702 | if (!UpdateAgent(reg, finalDestination, agent, sp)) |
666 | { | 703 | { |
667 | // Region doesn't take it | 704 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
705 | { | ||
706 | m_log.DebugFormat( | ||
707 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", | ||
708 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
709 | |||
710 | return; | ||
711 | } | ||
712 | |||
668 | m_log.WarnFormat( | 713 | m_log.WarnFormat( |
669 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", | 714 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", |
670 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 715 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
671 | 716 | ||
672 | Fail(sp, finalDestination, logout); | 717 | Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); |
673 | return; | 718 | return; |
674 | } | 719 | } |
675 | 720 | ||
@@ -679,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
679 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", | 724 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", |
680 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 725 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
681 | 726 | ||
682 | CleanupAbortedInterRegionTeleport(sp, finalDestination); | 727 | CleanupFailedInterRegionTeleport(sp, finalDestination); |
683 | 728 | ||
684 | return; | 729 | return; |
685 | } | 730 | } |
@@ -688,6 +733,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
688 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", | 733 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", |
689 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); | 734 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); |
690 | 735 | ||
736 | // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, | ||
737 | // where that neighbour simulator could otherwise request a child agent create on the source which then | ||
738 | // closes our existing agent which is still signalled as root. | ||
739 | sp.IsChildAgent = true; | ||
740 | |||
691 | if (m_eqModule != null) | 741 | if (m_eqModule != null) |
692 | { | 742 | { |
693 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); | 743 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); |
@@ -698,19 +748,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
698 | teleportFlags, capsPath); | 748 | teleportFlags, capsPath); |
699 | } | 749 | } |
700 | 750 | ||
701 | // Let's set this to true tentatively. This does not trigger OnChildAgent | ||
702 | sp.IsChildAgent = true; | ||
703 | |||
704 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 751 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which |
705 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | 752 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation |
706 | // that the client contacted the destination before we close things here. | 753 | // that the client contacted the destination before we close things here. |
707 | if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) | 754 | if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) |
708 | { | 755 | { |
756 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
757 | { | ||
758 | m_log.DebugFormat( | ||
759 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", | ||
760 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
761 | |||
762 | return; | ||
763 | } | ||
764 | |||
709 | m_log.WarnFormat( | 765 | m_log.WarnFormat( |
710 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | 766 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", |
711 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 767 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
712 | 768 | ||
713 | Fail(sp, finalDestination, logout); | 769 | Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); |
714 | return; | 770 | return; |
715 | } | 771 | } |
716 | 772 | ||
@@ -733,8 +789,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
733 | // Now let's make it officially a child agent | 789 | // Now let's make it officially a child agent |
734 | sp.MakeChildAgent(); | 790 | sp.MakeChildAgent(); |
735 | 791 | ||
736 | // sp.Scene.CleanDroppedAttachments(); | ||
737 | |||
738 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 792 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
739 | 793 | ||
740 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 794 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
@@ -774,7 +828,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
774 | /// <remarks> | 828 | /// <remarks> |
775 | /// <param name='sp'> </param> | 829 | /// <param name='sp'> </param> |
776 | /// <param name='finalDestination'></param> | 830 | /// <param name='finalDestination'></param> |
777 | protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) | 831 | protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) |
778 | { | 832 | { |
779 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | 833 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
780 | 834 | ||
@@ -793,12 +847,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
793 | /// <param name='sp'></param> | 847 | /// <param name='sp'></param> |
794 | /// <param name='finalDestination'></param> | 848 | /// <param name='finalDestination'></param> |
795 | /// <param name='logout'></param> | 849 | /// <param name='logout'></param> |
796 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) | 850 | /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> |
851 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) | ||
797 | { | 852 | { |
798 | CleanupAbortedInterRegionTeleport(sp, finalDestination); | 853 | CleanupFailedInterRegionTeleport(sp, finalDestination); |
799 | 854 | ||
800 | sp.ControllingClient.SendTeleportFailed( | 855 | sp.ControllingClient.SendTeleportFailed( |
801 | string.Format("Problems connecting to destination {0}", finalDestination.RegionName)); | 856 | string.Format( |
857 | "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason)); | ||
858 | |||
802 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); | 859 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); |
803 | } | 860 | } |
804 | 861 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index 8b2cd09..e903383 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | |||
@@ -51,11 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
51 | /// This is a state machine. | 51 | /// This is a state machine. |
52 | /// | 52 | /// |
53 | /// [Entry] => Preparing | 53 | /// [Entry] => Preparing |
54 | /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] } | 54 | /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] } |
55 | /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp } | 55 | /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting } |
56 | /// Cancelling => CleaningUp | 56 | /// Cancelling => CleaningUp || Aborting |
57 | /// ReceivedAtDestination => CleaningUp | 57 | /// ReceivedAtDestination => CleaningUp || Aborting |
58 | /// CleaningUp => [Exit] | 58 | /// CleaningUp => [Exit] |
59 | /// Aborting => [Exit] | ||
59 | /// | 60 | /// |
60 | /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp | 61 | /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp |
61 | /// However, any state can transition to CleaningUp if the teleport has failed. | 62 | /// However, any state can transition to CleaningUp if the teleport has failed. |
@@ -66,7 +67,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
66 | Transferring, // The agent is in the process of being transferred to a destination | 67 | Transferring, // The agent is in the process of being transferred to a destination |
67 | ReceivedAtDestination, // The destination has notified us that the agent has been successfully received | 68 | ReceivedAtDestination, // The destination has notified us that the agent has been successfully received |
68 | CleaningUp, // The agent is being changed to child/removed after a transfer | 69 | CleaningUp, // The agent is being changed to child/removed after a transfer |
69 | Cancelling // The user has cancelled the teleport but we have yet to act upon this. | 70 | Cancelling, // The user has cancelled the teleport but we have yet to act upon this. |
71 | Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed | ||
70 | } | 72 | } |
71 | 73 | ||
72 | /// <summary> | 74 | /// <summary> |
@@ -134,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
134 | // Illegal to try and update an agent that's not actually in transit. | 136 | // Illegal to try and update an agent that's not actually in transit. |
135 | if (!m_agentsInTransit.ContainsKey(id)) | 137 | if (!m_agentsInTransit.ContainsKey(id)) |
136 | { | 138 | { |
137 | if (newState != AgentTransferState.Cancelling) | 139 | if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting) |
138 | failureMessage = string.Format( | 140 | failureMessage = string.Format( |
139 | "Agent with ID {0} is not registered as in transit in {1}", | 141 | "Agent with ID {0} is not registered as in transit in {1}", |
140 | id, m_mod.Scene.RegionInfo.RegionName); | 142 | id, m_mod.Scene.RegionInfo.RegionName); |
@@ -145,7 +147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
145 | { | 147 | { |
146 | oldState = m_agentsInTransit[id]; | 148 | oldState = m_agentsInTransit[id]; |
147 | 149 | ||
148 | if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) | 150 | if (newState == AgentTransferState.Aborting) |
151 | { | ||
152 | transitionOkay = true; | ||
153 | } | ||
154 | else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) | ||
149 | { | 155 | { |
150 | transitionOkay = true; | 156 | transitionOkay = true; |
151 | } | 157 | } |
@@ -292,8 +298,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
292 | 298 | ||
293 | // There should be no race condition here since no other code should be removing the agent transfer or | 299 | // There should be no race condition here since no other code should be removing the agent transfer or |
294 | // changing the state to another other than Transferring => ReceivedAtDestination. | 300 | // changing the state to another other than Transferring => ReceivedAtDestination. |
295 | while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) | 301 | |
302 | while (count-- > 0) | ||
296 | { | 303 | { |
304 | lock (m_agentsInTransit) | ||
305 | { | ||
306 | if (m_agentsInTransit[id] == AgentTransferState.ReceivedAtDestination) | ||
307 | break; | ||
308 | } | ||
309 | |||
297 | // m_log.Debug(" >>> Waiting... " + count); | 310 | // m_log.Debug(" >>> Waiting... " + count); |
298 | Thread.Sleep(100); | 311 | Thread.Sleep(100); |
299 | } | 312 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs index 3c8e0ef..2fe9026 100755 --- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs +++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs | |||
@@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging | |||
136 | { | 136 | { |
137 | lock (m_logFileWriteLock) | 137 | lock (m_logFileWriteLock) |
138 | { | 138 | { |
139 | DateTime now = DateTime.Now; | 139 | DateTime now = DateTime.UtcNow; |
140 | if (m_logFile == null || now > m_logFileEndTime) | 140 | if (m_logFile == null || now > m_logFileEndTime) |
141 | { | 141 | { |
142 | if (m_logFile != null) | 142 | if (m_logFile != null) |