diff options
author | diva | 2008-12-22 07:06:01 +0000 |
---|---|---|
committer | diva | 2008-12-22 07:06:01 +0000 |
commit | 339fd602db4a0182777c9acc0b7486d91e9f904d (patch) | |
tree | 8291d3d4e847d1cee8f51c255512360448058bdd | |
parent | Removing the region where the agent is in from the list of regions to close c... (diff) | |
download | opensim-SC_OLD-339fd602db4a0182777c9acc0b7486d91e9f904d.zip opensim-SC_OLD-339fd602db4a0182777c9acc0b7486d91e9f904d.tar.gz opensim-SC_OLD-339fd602db4a0182777c9acc0b7486d91e9f904d.tar.bz2 opensim-SC_OLD-339fd602db4a0182777c9acc0b7486d91e9f904d.tar.xz |
This commit is a major change on the TP process. Several things were wrong and/or broken. (a) ExpectAvatarCrossing is redundant (and bad) because the client triggers the same method on the receiving region after it receives TeleportFinish. (b) At least two of the *Async methods in SceneCommunicationService weren't asynchronous at all; I made them be asynchronous. Crossing fingers...
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs | 42 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | 124 |
2 files changed, 96 insertions, 70 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs index ced5b86..78d5725 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs | |||
@@ -196,20 +196,20 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
196 | agent.InventoryFolder = UUID.Zero; | 196 | agent.InventoryFolder = UUID.Zero; |
197 | agent.startpos = position; | 197 | agent.startpos = position; |
198 | agent.child = true; | 198 | agent.child = true; |
199 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) | 199 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
200 | { | 200 | { |
201 | Thread.Sleep(2000); | 201 | // brand new agent, let's create a new caps seed |
202 | |||
203 | // brand new agent | ||
204 | agent.CapsPath = Util.GetRandomCapsPath(); | 202 | agent.CapsPath = Util.GetRandomCapsPath(); |
205 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) | 203 | } |
206 | { | ||
207 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
208 | return; | ||
209 | } | ||
210 | 204 | ||
211 | Thread.Sleep(3000); | 205 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) |
206 | { | ||
207 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
208 | return; | ||
209 | } | ||
212 | 210 | ||
211 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) | ||
212 | { | ||
213 | // TODO Should construct this behind a method | 213 | // TODO Should construct this behind a method |
214 | capsPath = | 214 | capsPath = |
215 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | 215 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort |
@@ -220,6 +220,11 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
220 | OSD Item = EventQueueHelper.EnableSimulator(realHandle, endPoint); | 220 | OSD Item = EventQueueHelper.EnableSimulator(realHandle, endPoint); |
221 | eq.Enqueue(Item, avatar.UUID); | 221 | eq.Enqueue(Item, avatar.UUID); |
222 | 222 | ||
223 | // ES makes the client send a UseCircuitCode message to the destination, | ||
224 | // which triggers a bunch of things there. | ||
225 | // So let's wait | ||
226 | Thread.Sleep(2000); | ||
227 | |||
223 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); | 228 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); |
224 | eq.Enqueue(Item, avatar.UUID); | 229 | eq.Enqueue(Item, avatar.UUID); |
225 | } | 230 | } |
@@ -237,8 +242,8 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
237 | + "/CAPS/" + agent.CapsPath + "0000/"; | 242 | + "/CAPS/" + agent.CapsPath + "0000/"; |
238 | } | 243 | } |
239 | 244 | ||
240 | m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | 245 | //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, |
241 | position, false); | 246 | // position, false); |
242 | 247 | ||
243 | //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | 248 | //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, |
244 | // position, false)) | 249 | // position, false)) |
@@ -251,7 +256,9 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
251 | // return; | 256 | // return; |
252 | //} | 257 | //} |
253 | 258 | ||
254 | Thread.Sleep(7000); | 259 | avatar.MakeChildAgent(); |
260 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | ||
261 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | ||
255 | 262 | ||
256 | m_log.DebugFormat( | 263 | m_log.DebugFormat( |
257 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", agent.CapsPath, avatar.UUID); | 264 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", agent.CapsPath, avatar.UUID); |
@@ -276,9 +283,6 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
276 | /// Hypergrid mod stop | 283 | /// Hypergrid mod stop |
277 | /// | 284 | /// |
278 | 285 | ||
279 | avatar.MakeChildAgent(); | ||
280 | Thread.Sleep(3000); | ||
281 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | ||
282 | if (KiPrimitive != null) | 286 | if (KiPrimitive != null) |
283 | { | 287 | { |
284 | KiPrimitive(avatar.LocalId); | 288 | KiPrimitive(avatar.LocalId); |
@@ -293,7 +297,11 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid | |||
293 | /// | 297 | /// |
294 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) | 298 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) |
295 | { | 299 | { |
296 | Thread.Sleep(5000); | 300 | // FinishTeleport makes the client send CompleteMovementIntoRegion (at the destination), which |
301 | // trigers a whole shebang of things there. So let's wait plenty before we disconnect. | ||
302 | // The user is already there anyway. | ||
303 | Thread.Sleep(8000); | ||
304 | avatar.Close(); | ||
297 | CloseConnection(avatar.UUID); | 305 | CloseConnection(avatar.UUID); |
298 | } | 306 | } |
299 | // if (teleport success) // seems to be always success here | 307 | // if (teleport success) // seems to be always success here |
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 2b30c0d..98ea879 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | |||
@@ -531,7 +531,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
531 | //bool val = m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region)); | 531 | //bool val = m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region)); |
532 | } | 532 | } |
533 | 533 | ||
534 | public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); | 534 | public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ulong regionHandle); |
535 | 535 | ||
536 | /// <summary> | 536 | /// <summary> |
537 | /// This informs all neighboring regions about the settings of it's child agent. | 537 | /// This informs all neighboring regions about the settings of it's child agent. |
@@ -540,30 +540,28 @@ namespace OpenSim.Region.Environment.Scenes | |||
540 | /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. | 540 | /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. |
541 | /// | 541 | /// |
542 | /// </summary> | 542 | /// </summary> |
543 | private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence) | 543 | private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ulong regionHandle) |
544 | { | 544 | { |
545 | //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + presence.Scene.RegionInfo.RegionName); | 545 | //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + presence.Scene.RegionInfo.RegionName); |
546 | //bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | ||
546 | try | 547 | try |
547 | { | 548 | { |
548 | foreach (ulong regionHandle in presence.KnownChildRegionHandles) | 549 | m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); |
549 | { | ||
550 | bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | ||
551 | |||
552 | if (regionAccepted) | ||
553 | { | ||
554 | //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent"); | ||
555 | } | ||
556 | else | ||
557 | { | ||
558 | //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent"); | ||
559 | } | ||
560 | } | ||
561 | } | 550 | } |
562 | catch (InvalidOperationException) | 551 | catch |
563 | { | 552 | { |
564 | // We're ignoring a collection was modified error because this data gets old and outdated fast. | 553 | // Ignore; we did our best |
565 | } | 554 | } |
566 | 555 | ||
556 | //if (regionAccepted) | ||
557 | //{ | ||
558 | // //m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent"); | ||
559 | //} | ||
560 | //else | ||
561 | //{ | ||
562 | // //m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent"); | ||
563 | //} | ||
564 | |||
567 | } | 565 | } |
568 | 566 | ||
569 | private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) | 567 | private void SendChildAgentDataUpdateCompleted(IAsyncResult iar) |
@@ -575,27 +573,37 @@ namespace OpenSim.Region.Environment.Scenes | |||
575 | public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence) | 573 | public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence) |
576 | { | 574 | { |
577 | // This assumes that we know what our neighbors are. | 575 | // This assumes that we know what our neighbors are. |
578 | SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; | 576 | try |
579 | d.BeginInvoke(cAgentData,presence, | 577 | { |
580 | SendChildAgentDataUpdateCompleted, | 578 | foreach (ulong regionHandle in presence.KnownChildRegionHandles) |
581 | d); | 579 | { |
580 | |||
581 | SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; | ||
582 | d.BeginInvoke(cAgentData, regionHandle, | ||
583 | SendChildAgentDataUpdateCompleted, | ||
584 | d); | ||
585 | } | ||
586 | } | ||
587 | catch (InvalidOperationException) | ||
588 | { | ||
589 | // We're ignoring a collection was modified error because this data gets old and outdated fast. | ||
590 | } | ||
591 | |||
582 | } | 592 | } |
583 | 593 | ||
584 | public delegate void SendCloseChildAgentDelegate(UUID agentID, List<ulong> regionlst); | 594 | public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle); |
585 | 595 | ||
586 | /// <summary> | 596 | /// <summary> |
587 | /// This Closes child agents on neighboring regions | 597 | /// This Closes child agents on neighboring regions |
588 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 598 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
589 | /// </summary> | 599 | /// </summary> |
590 | protected void SendCloseChildAgentAsync(UUID agentID, List<ulong> regionlst) | 600 | protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle) |
591 | { | 601 | { |
592 | 602 | ||
593 | foreach (ulong regionHandle in regionlst) | 603 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); |
594 | { | 604 | //bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); |
595 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); | 605 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. |
596 | //bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | 606 | m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); |
597 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. | ||
598 | m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | ||
599 | 607 | ||
600 | //if (regionAccepted) | 608 | //if (regionAccepted) |
601 | //{ | 609 | //{ |
@@ -608,7 +616,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
608 | 616 | ||
609 | //} | 617 | //} |
610 | 618 | ||
611 | } | ||
612 | //// We remove the list of known regions from the agent's known region list through an event | 619 | //// We remove the list of known regions from the agent's known region list through an event |
613 | //// to scene, because, if an agent logged of, it's likely that there will be no scene presence | 620 | //// to scene, because, if an agent logged of, it's likely that there will be no scene presence |
614 | //// by the time we get to this part of the method. | 621 | //// by the time we get to this part of the method. |
@@ -627,11 +634,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
627 | 634 | ||
628 | public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst) | 635 | public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst) |
629 | { | 636 | { |
630 | // This assumes that we know what our neighbors are. | 637 | foreach (ulong handle in regionslst) |
631 | SendCloseChildAgentDelegate d = SendCloseChildAgentAsync; | 638 | { |
632 | d.BeginInvoke(agentID, regionslst, | 639 | SendCloseChildAgentDelegate d = SendCloseChildAgentAsync; |
633 | SendCloseChildAgentCompleted, | 640 | d.BeginInvoke(agentID, handle, |
634 | d); | 641 | SendCloseChildAgentCompleted, |
642 | d); | ||
643 | } | ||
635 | } | 644 | } |
636 | 645 | ||
637 | /// <summary> | 646 | /// <summary> |
@@ -681,6 +690,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
681 | public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, | 690 | public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, |
682 | Vector3 lookAt, uint teleportFlags) | 691 | Vector3 lookAt, uint teleportFlags) |
683 | { | 692 | { |
693 | m_log.DebugFormat("[SCENE COMMUNICATION SERVICE] RequestTeleportToLocation {0} ", position.ToString()); | ||
694 | |||
684 | if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) | 695 | if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) |
685 | return; | 696 | return; |
686 | 697 | ||
@@ -784,18 +795,18 @@ namespace OpenSim.Region.Environment.Scenes | |||
784 | agent.child = true; | 795 | agent.child = true; |
785 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 796 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
786 | { | 797 | { |
787 | Thread.Sleep(2000); | 798 | // brand new agent, let's create a new caps seed |
788 | |||
789 | // brand new agent | ||
790 | agent.CapsPath = Util.GetRandomCapsPath(); | 799 | agent.CapsPath = Util.GetRandomCapsPath(); |
791 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) | 800 | } |
792 | { | ||
793 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
794 | return; | ||
795 | } | ||
796 | 801 | ||
797 | Thread.Sleep(3000); | 802 | if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent)) |
803 | { | ||
804 | avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports."); | ||
805 | return; | ||
806 | } | ||
798 | 807 | ||
808 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
809 | { | ||
799 | // TODO Should construct this behind a method | 810 | // TODO Should construct this behind a method |
800 | capsPath = | 811 | capsPath = |
801 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | 812 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort |
@@ -806,6 +817,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
806 | OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, endPoint); | 817 | OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, endPoint); |
807 | eq.Enqueue(Item, avatar.UUID); | 818 | eq.Enqueue(Item, avatar.UUID); |
808 | 819 | ||
820 | // ES makes the client send a UseCircuitCode message to the destination, | ||
821 | // which triggers a bunch of things there. | ||
822 | // So let's wait | ||
823 | Thread.Sleep(2000); | ||
824 | |||
809 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); | 825 | Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath); |
810 | eq.Enqueue(Item, avatar.UUID); | 826 | eq.Enqueue(Item, avatar.UUID); |
811 | } | 827 | } |
@@ -824,8 +840,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
824 | // Expect avatar crossing is a heavy-duty function at the destination. | 840 | // Expect avatar crossing is a heavy-duty function at the destination. |
825 | // That is where MakeRoot is called, which fetches appearance and inventory. | 841 | // That is where MakeRoot is called, which fetches appearance and inventory. |
826 | // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. | 842 | // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. |
827 | m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | 843 | //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, |
828 | position, false); | 844 | // position, false); |
845 | |||
829 | //{ | 846 | //{ |
830 | // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); | 847 | // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); |
831 | // // We should close that agent we just created over at destination... | 848 | // // We should close that agent we just created over at destination... |
@@ -835,7 +852,9 @@ namespace OpenSim.Region.Environment.Scenes | |||
835 | // return; | 852 | // return; |
836 | //} | 853 | //} |
837 | 854 | ||
838 | Thread.Sleep(7000); | 855 | avatar.MakeChildAgent(); |
856 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | ||
857 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | ||
839 | 858 | ||
840 | m_log.DebugFormat( | 859 | m_log.DebugFormat( |
841 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); | 860 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); |
@@ -853,9 +872,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
853 | teleportFlags, capsPath); | 872 | teleportFlags, capsPath); |
854 | } | 873 | } |
855 | 874 | ||
856 | avatar.MakeChildAgent(); | ||
857 | Thread.Sleep(3000); | ||
858 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | ||
859 | if (KiPrimitive != null) | 875 | if (KiPrimitive != null) |
860 | { | 876 | { |
861 | KiPrimitive(avatar.LocalId); | 877 | KiPrimitive(avatar.LocalId); |
@@ -866,7 +882,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
866 | 882 | ||
867 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 883 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
868 | { | 884 | { |
869 | Thread.Sleep(5000); | 885 | // FinishTeleport makes the client send CompleteMovementIntoRegion (at the destination), which |
886 | // trigers a whole shebang of things there. So let's wait plenty before we disconnect. | ||
887 | // The user is already there anyway. | ||
888 | Thread.Sleep(8000); | ||
889 | avatar.Close(); | ||
870 | CloseConnection(avatar.UUID); | 890 | CloseConnection(avatar.UUID); |
871 | } | 891 | } |
872 | 892 | ||
@@ -879,8 +899,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
879 | m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); | 899 | m_log.InfoFormat("User {0} is going to another region, profile cache removed", avatar.UUID); |
880 | } | 900 | } |
881 | 901 | ||
882 | // Close this ScenePresence too | ||
883 | //avatar.Close(); | ||
884 | 902 | ||
885 | } | 903 | } |
886 | else | 904 | else |