diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer')
3 files changed, 560 insertions, 486 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index e4bc113..ed93f05 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -147,13 +147,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
147 | // Add this agent in this region as a banned person | 147 | // Add this agent in this region as a banned person |
148 | public void Add(ulong pRegionHandle, UUID pAgentID) | 148 | public void Add(ulong pRegionHandle, UUID pAgentID) |
149 | { | 149 | { |
150 | this.Add(pRegionHandle, pAgentID, 45, 15); | ||
151 | } | ||
152 | |||
153 | public void Add(ulong pRegionHandle, UUID pAgentID, double newTime, double extendTime) | ||
154 | { | ||
150 | if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) | 155 | if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) |
151 | { | 156 | { |
152 | m_idCache = new ExpiringCache<ulong, DateTime>(); | 157 | m_idCache = new ExpiringCache<ulong, DateTime>(); |
153 | m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45)); | 158 | m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime)); |
154 | } | 159 | } |
155 | m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 160 | m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(extendTime), TimeSpan.FromSeconds(extendTime)); |
156 | } | 161 | } |
162 | |||
157 | // Remove the agent from the region's banned list | 163 | // Remove the agent from the region's banned list |
158 | public void Remove(ulong pRegionHandle, UUID pAgentID) | 164 | public void Remove(ulong pRegionHandle, UUID pAgentID) |
159 | { | 165 | { |
@@ -163,6 +169,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
163 | } | 169 | } |
164 | } | 170 | } |
165 | } | 171 | } |
172 | |||
166 | private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); | 173 | private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); |
167 | 174 | ||
168 | private IEventQueue m_eqModule; | 175 | private IEventQueue m_eqModule; |
@@ -451,16 +458,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
451 | } | 458 | } |
452 | 459 | ||
453 | // TODO: Get proper AVG Height | 460 | // TODO: Get proper AVG Height |
454 | float localAVHeight = 1.56f; | 461 | float localHalfAVHeight = 0.8f; |
462 | if (sp.Appearance != null) | ||
463 | localHalfAVHeight = sp.Appearance.AvatarHeight / 2; | ||
464 | |||
455 | float posZLimit = 22; | 465 | float posZLimit = 22; |
456 | 466 | ||
457 | // TODO: Check other Scene HeightField | 467 | // TODO: Check other Scene HeightField |
458 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | 468 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; |
459 | 469 | ||
460 | float newPosZ = posZLimit + localAVHeight; | 470 | posZLimit += localHalfAVHeight + 0.1f; |
461 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 471 | |
472 | if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit))) | ||
462 | { | 473 | { |
463 | position.Z = newPosZ; | 474 | position.Z = posZLimit; |
464 | } | 475 | } |
465 | 476 | ||
466 | if (sp.Flying) | 477 | if (sp.Flying) |
@@ -559,9 +570,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
559 | Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY); | 570 | Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY); |
560 | 571 | ||
561 | MapBlockData block = new MapBlockData(); | 572 | MapBlockData block = new MapBlockData(); |
562 | block.X = (ushort)regX; | 573 | block.X = (ushort)(regX); |
563 | block.Y = (ushort)regY; | 574 | block.Y = (ushort)(regY); |
564 | block.Access = (byte)SimAccess.Down; | 575 | block.Access = (byte)SimAccess.Down; // == not there |
565 | 576 | ||
566 | List<MapBlockData> blocks = new List<MapBlockData>(); | 577 | List<MapBlockData> blocks = new List<MapBlockData>(); |
567 | blocks.Add(block); | 578 | blocks.Add(block); |
@@ -696,10 +707,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
696 | return; | 707 | return; |
697 | } | 708 | } |
698 | 709 | ||
699 | uint newRegionX, newRegionY, oldRegionX, oldRegionY; | ||
700 | Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY); | ||
701 | Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY); | ||
702 | |||
703 | ulong destinationHandle = finalDestination.RegionHandle; | 710 | ulong destinationHandle = finalDestination.RegionHandle; |
704 | 711 | ||
705 | // Let's do DNS resolution only once in this process, please! | 712 | // Let's do DNS resolution only once in this process, please! |
@@ -768,7 +775,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
768 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | 775 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); |
769 | agentCircuit.startpos = position; | 776 | agentCircuit.startpos = position; |
770 | agentCircuit.child = true; | 777 | agentCircuit.child = true; |
771 | agentCircuit.Appearance = sp.Appearance; | 778 | |
779 | // agentCircuit.Appearance = sp.Appearance; | ||
780 | // agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false); | ||
781 | agentCircuit.Appearance = new AvatarAppearance(); | ||
782 | agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; | ||
783 | |||
772 | if (currentAgentCircuit != null) | 784 | if (currentAgentCircuit != null) |
773 | { | 785 | { |
774 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; | 786 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; |
@@ -779,24 +791,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
779 | agentCircuit.Id0 = currentAgentCircuit.Id0; | 791 | agentCircuit.Id0 = currentAgentCircuit.Id0; |
780 | } | 792 | } |
781 | 793 | ||
782 | // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 794 | IClientIPEndpoint ipepClient; |
783 | float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance, | 795 | |
784 | (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY)); | 796 | uint newRegionX, newRegionY, oldRegionX, oldRegionY; |
785 | if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 797 | Util.RegionHandleToRegionLoc(destinationHandle, out newRegionX, out newRegionY); |
798 | Util.RegionHandleToRegionLoc(sourceRegion.RegionHandle, out oldRegionX, out oldRegionY); | ||
799 | int oldSizeX = (int)sourceRegion.RegionSizeX; | ||
800 | int oldSizeY = (int)sourceRegion.RegionSizeY; | ||
801 | int newSizeX = finalDestination.RegionSizeX; | ||
802 | int newSizeY = finalDestination.RegionSizeY; | ||
803 | |||
804 | bool OutSideViewRange = NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, | ||
805 | oldSizeX, oldSizeY, newSizeX, newSizeY); | ||
806 | |||
807 | if (OutSideViewRange) | ||
786 | { | 808 | { |
787 | // brand new agent, let's create a new caps seed | 809 | m_log.DebugFormat( |
810 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", | ||
811 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
812 | |||
813 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
814 | #region IP Translation for NAT | ||
815 | // Uses ipepClient above | ||
816 | if (sp.ClientView.TryGet(out ipepClient)) | ||
817 | { | ||
818 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
819 | } | ||
820 | #endregion | ||
788 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 821 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
789 | } | 822 | } |
823 | else | ||
824 | { | ||
825 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
826 | if (agentCircuit.CapsPath == null) | ||
827 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | ||
828 | } | ||
790 | 829 | ||
791 | // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 | 830 | // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 |
792 | if (ctx.OutboundVersion >= 0.2f) | 831 | if (ctx.OutboundVersion >= 0.2f) |
793 | TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); | 832 | TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange , ctx, out reason); |
794 | else | 833 | else |
795 | TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); | 834 | TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange, ctx, out reason); |
796 | } | 835 | } |
797 | 836 | ||
798 | private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | 837 | private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, |
799 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) | 838 | IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason) |
800 | { | 839 | { |
801 | ulong destinationHandle = finalDestination.RegionHandle; | 840 | ulong destinationHandle = finalDestination.RegionHandle; |
802 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 841 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
@@ -805,10 +844,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
805 | "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", | 844 | "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", |
806 | sp.Name, Scene.Name, finalDestination.RegionName); | 845 | sp.Name, Scene.Name, finalDestination.RegionName); |
807 | 846 | ||
847 | string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
848 | |||
808 | // Let's create an agent there if one doesn't exist yet. | 849 | // Let's create an agent there if one doesn't exist yet. |
809 | // NOTE: logout will always be false for a non-HG teleport. | 850 | // NOTE: logout will always be false for a non-HG teleport. |
810 | bool logout = false; | 851 | bool logout = false; |
811 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 852 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout)) |
812 | { | 853 | { |
813 | m_interRegionTeleportFailures.Value++; | 854 | m_interRegionTeleportFailures.Value++; |
814 | 855 | ||
@@ -846,28 +887,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
846 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 887 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
847 | 888 | ||
848 | // OK, it got this agent. Let's close some child agents | 889 | // OK, it got this agent. Let's close some child agents |
849 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
850 | 890 | ||
851 | IClientIPEndpoint ipepClient; | 891 | if (OutSideViewRange) |
852 | string capsPath = String.Empty; | ||
853 | float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance, | ||
854 | (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY)); | ||
855 | if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
856 | { | 892 | { |
857 | m_log.DebugFormat( | ||
858 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", | ||
859 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
860 | |||
861 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
862 | #region IP Translation for NAT | ||
863 | // Uses ipepClient above | ||
864 | if (sp.ClientView.TryGet(out ipepClient)) | ||
865 | { | ||
866 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
867 | } | ||
868 | #endregion | ||
869 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
870 | |||
871 | if (m_eqModule != null) | 893 | if (m_eqModule != null) |
872 | { | 894 | { |
873 | // The EnableSimulator message makes the client establish a connection with the destination | 895 | // The EnableSimulator message makes the client establish a connection with the destination |
@@ -897,15 +919,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
897 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | 919 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); |
898 | } | 920 | } |
899 | } | 921 | } |
900 | else | ||
901 | { | ||
902 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
903 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
904 | } | ||
905 | 922 | ||
906 | // Let's send a full update of the agent. This is a synchronous call. | 923 | // Let's send a full update of the agent. This is a synchronous call. |
907 | AgentData agent = new AgentData(); | 924 | AgentData agent = new AgentData(); |
908 | sp.CopyTo(agent); | 925 | sp.CopyTo(agent); |
926 | |||
927 | if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0) | ||
928 | agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
929 | |||
909 | agent.Position = agentCircuit.startpos; | 930 | agent.Position = agentCircuit.startpos; |
910 | SetCallbackURL(agent, sp.Scene.RegionInfo); | 931 | SetCallbackURL(agent, sp.Scene.RegionInfo); |
911 | 932 | ||
@@ -927,7 +948,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
927 | // destination region but the viewer cannot establish the connection (e.g. due to network issues between | 948 | // destination region but the viewer cannot establish the connection (e.g. due to network issues between |
928 | // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then | 949 | // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then |
929 | // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). | 950 | // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). |
930 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | 951 | if (!UpdateAgent(reg, finalDestination, agent, sp, ctx)) |
931 | { | 952 | { |
932 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 953 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
933 | { | 954 | { |
@@ -1007,7 +1028,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1007 | return; | 1028 | return; |
1008 | } | 1029 | } |
1009 | 1030 | ||
1010 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
1011 | 1031 | ||
1012 | /* | 1032 | /* |
1013 | // TODO: This may be 0.6. Check if still needed | 1033 | // TODO: This may be 0.6. Check if still needed |
@@ -1020,18 +1040,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1020 | } | 1040 | } |
1021 | */ | 1041 | */ |
1022 | 1042 | ||
1023 | // May need to logout or other cleanup | 1043 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
1024 | AgentHasMovedAway(sp, logout); | ||
1025 | 1044 | ||
1026 | // Well, this is it. The agent is over there. | 1045 | sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); |
1027 | KillEntity(sp.Scene, sp.LocalId); | ||
1028 | 1046 | ||
1029 | // Now let's make it officially a child agent | 1047 | // call HG hook |
1030 | sp.MakeChildAgent(); | 1048 | AgentHasMovedAway(sp, logout); |
1049 | |||
1050 | sp.HasMovedAway(!(OutSideViewRange || logout)); | ||
1051 | |||
1052 | // Now let's make it officially a child agent | ||
1053 | sp.MakeChildAgent(destinationHandle); | ||
1031 | 1054 | ||
1032 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1055 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1033 | 1056 | ||
1034 | if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1057 | if (NeedsClosing(reg, OutSideViewRange)) |
1035 | { | 1058 | { |
1036 | if (!sp.Scene.IncomingPreCloseClient(sp)) | 1059 | if (!sp.Scene.IncomingPreCloseClient(sp)) |
1037 | return; | 1060 | return; |
@@ -1043,26 +1066,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1043 | // This sleep can be increased if necessary. However, whilst it's active, | 1066 | // This sleep can be increased if necessary. However, whilst it's active, |
1044 | // an agent cannot teleport back to this region if it has teleported away. | 1067 | // an agent cannot teleport back to this region if it has teleported away. |
1045 | Thread.Sleep(2000); | 1068 | Thread.Sleep(2000); |
1046 | 1069 | if (m_eqModule != null && !sp.DoNotCloseAfterTeleport) | |
1070 | m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID); | ||
1071 | Thread.Sleep(500); | ||
1047 | sp.Scene.CloseAgent(sp.UUID, false); | 1072 | sp.Scene.CloseAgent(sp.UUID, false); |
1048 | } | 1073 | } |
1049 | else | ||
1050 | { | ||
1051 | // now we have a child agent in this region. | ||
1052 | sp.Reset(); | ||
1053 | } | ||
1054 | } | 1074 | } |
1055 | 1075 | ||
1056 | private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | 1076 | private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, |
1057 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) | 1077 | IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason) |
1058 | { | 1078 | { |
1059 | ulong destinationHandle = finalDestination.RegionHandle; | 1079 | ulong destinationHandle = finalDestination.RegionHandle; |
1060 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 1080 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
1061 | 1081 | ||
1082 | string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);; | ||
1083 | |||
1062 | // Let's create an agent there if one doesn't exist yet. | 1084 | // Let's create an agent there if one doesn't exist yet. |
1063 | // NOTE: logout will always be false for a non-HG teleport. | 1085 | // NOTE: logout will always be false for a non-HG teleport. |
1064 | bool logout = false; | 1086 | bool logout = false; |
1065 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 1087 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout)) |
1066 | { | 1088 | { |
1067 | m_interRegionTeleportFailures.Value++; | 1089 | m_interRegionTeleportFailures.Value++; |
1068 | 1090 | ||
@@ -1099,32 +1121,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1099 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. | 1121 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. |
1100 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 1122 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
1101 | 1123 | ||
1102 | IClientIPEndpoint ipepClient; | ||
1103 | string capsPath = String.Empty; | ||
1104 | float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance, | ||
1105 | (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY)); | ||
1106 | if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
1107 | { | ||
1108 | m_log.DebugFormat( | ||
1109 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", | ||
1110 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
1111 | |||
1112 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
1113 | #region IP Translation for NAT | ||
1114 | // Uses ipepClient above | ||
1115 | if (sp.ClientView.TryGet(out ipepClient)) | ||
1116 | { | ||
1117 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
1118 | } | ||
1119 | #endregion | ||
1120 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
1121 | } | ||
1122 | else | ||
1123 | { | ||
1124 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
1125 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
1126 | } | ||
1127 | |||
1128 | // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, | 1124 | // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, |
1129 | // where that neighbour simulator could otherwise request a child agent create on the source which then | 1125 | // where that neighbour simulator could otherwise request a child agent create on the source which then |
1130 | // closes our existing agent which is still signalled as root. | 1126 | // closes our existing agent which is still signalled as root. |
@@ -1146,6 +1142,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1146 | AgentData agent = new AgentData(); | 1142 | AgentData agent = new AgentData(); |
1147 | sp.CopyTo(agent); | 1143 | sp.CopyTo(agent); |
1148 | agent.Position = agentCircuit.startpos; | 1144 | agent.Position = agentCircuit.startpos; |
1145 | |||
1146 | if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0) | ||
1147 | agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
1148 | |||
1149 | agent.SenderWantsToWaitForRoot = true; | 1149 | agent.SenderWantsToWaitForRoot = true; |
1150 | //SetCallbackURL(agent, sp.Scene.RegionInfo); | 1150 | //SetCallbackURL(agent, sp.Scene.RegionInfo); |
1151 | 1151 | ||
@@ -1158,7 +1158,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1158 | // Send the Update. If this returns true, we know the client has contacted the destination | 1158 | // Send the Update. If this returns true, we know the client has contacted the destination |
1159 | // via CompleteMovementIntoRegion, so we can let go. | 1159 | // via CompleteMovementIntoRegion, so we can let go. |
1160 | // If it returns false, something went wrong, and we need to abort. | 1160 | // If it returns false, something went wrong, and we need to abort. |
1161 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | 1161 | if (!UpdateAgent(reg, finalDestination, agent, sp, ctx)) |
1162 | { | 1162 | { |
1163 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | 1163 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) |
1164 | { | 1164 | { |
@@ -1187,19 +1187,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1187 | // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex | 1187 | // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex |
1188 | // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are | 1188 | // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are |
1189 | // abandoned without proper close by viewer but then re-used by an incoming connection. | 1189 | // abandoned without proper close by viewer but then re-used by an incoming connection. |
1190 | sp.CloseChildAgents(newRegionX, newRegionY); | 1190 | sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); |
1191 | 1191 | ||
1192 | // May need to logout or other cleanup | 1192 | sp.HasMovedAway(!(OutSideViewRange || logout)); |
1193 | AgentHasMovedAway(sp, logout); | ||
1194 | 1193 | ||
1195 | // Well, this is it. The agent is over there. | 1194 | //HG hook |
1196 | KillEntity(sp.Scene, sp.LocalId); | 1195 | AgentHasMovedAway(sp, logout); |
1197 | 1196 | ||
1198 | // Now let's make it officially a child agent | 1197 | // Now let's make it officially a child agent |
1199 | sp.MakeChildAgent(); | 1198 | sp.MakeChildAgent(destinationHandle); |
1199 | |||
1200 | |||
1200 | 1201 | ||
1201 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 1202 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
1202 | if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 1203 | // go by HG hook |
1204 | if (NeedsClosing(reg, OutSideViewRange)) | ||
1203 | { | 1205 | { |
1204 | if (!sp.Scene.IncomingPreCloseClient(sp)) | 1206 | if (!sp.Scene.IncomingPreCloseClient(sp)) |
1205 | return; | 1207 | return; |
@@ -1210,8 +1212,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1210 | // BEFORE THEY SETTLE IN THE NEW REGION. | 1212 | // BEFORE THEY SETTLE IN THE NEW REGION. |
1211 | // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR | 1213 | // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR |
1212 | // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. | 1214 | // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. |
1213 | Thread.Sleep(15000); | 1215 | |
1214 | 1216 | Thread.Sleep(14000); | |
1217 | if (m_eqModule != null && !sp.DoNotCloseAfterTeleport) | ||
1218 | m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID); | ||
1219 | Thread.Sleep(1000); | ||
1220 | |||
1215 | // OK, it got this agent. Let's close everything | 1221 | // OK, it got this agent. Let's close everything |
1216 | // If we shouldn't close the agent due to some other region renewing the connection | 1222 | // If we shouldn't close the agent due to some other region renewing the connection |
1217 | // then this will be handled in IncomingCloseAgent under lock conditions | 1223 | // then this will be handled in IncomingCloseAgent under lock conditions |
@@ -1220,11 +1226,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1220 | 1226 | ||
1221 | sp.Scene.CloseAgent(sp.UUID, false); | 1227 | sp.Scene.CloseAgent(sp.UUID, false); |
1222 | } | 1228 | } |
1229 | /* | ||
1223 | else | 1230 | else |
1224 | { | 1231 | { |
1225 | // now we have a child agent in this region. | 1232 | // now we have a child agent in this region. |
1226 | sp.Reset(); | 1233 | sp.Reset(); |
1227 | } | 1234 | } |
1235 | */ | ||
1228 | } | 1236 | } |
1229 | 1237 | ||
1230 | /// <summary> | 1238 | /// <summary> |
@@ -1272,13 +1280,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1272 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); | 1280 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); |
1273 | } | 1281 | } |
1274 | 1282 | ||
1275 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 1283 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout) |
1276 | { | 1284 | { |
1277 | GridRegion source = new GridRegion(Scene.RegionInfo); | 1285 | GridRegion source = new GridRegion(Scene.RegionInfo); |
1278 | source.RawServerURI = m_GatekeeperURI; | 1286 | source.RawServerURI = m_GatekeeperURI; |
1279 | 1287 | ||
1280 | logout = false; | 1288 | logout = false; |
1281 | bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, out reason); | 1289 | bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, ctx, out reason); |
1282 | 1290 | ||
1283 | if (success) | 1291 | if (success) |
1284 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); | 1292 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); |
@@ -1286,9 +1294,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1286 | return success; | 1294 | return success; |
1287 | } | 1295 | } |
1288 | 1296 | ||
1289 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp) | 1297 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp, EntityTransferContext ctx) |
1290 | { | 1298 | { |
1291 | return Scene.SimulationService.UpdateAgent(finalDestination, agent); | 1299 | return Scene.SimulationService.UpdateAgent(finalDestination, agent, ctx); |
1292 | } | 1300 | } |
1293 | 1301 | ||
1294 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) | 1302 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) |
@@ -1305,10 +1313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1305 | /// </summary> | 1313 | /// </summary> |
1306 | /// <param name='sp'></param> | 1314 | /// <param name='sp'></param> |
1307 | /// <param name='logout'></param> | 1315 | /// <param name='logout'></param> |
1316 | /// | ||
1317 | /// now just a HG hook | ||
1308 | protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) | 1318 | protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) |
1309 | { | 1319 | { |
1310 | if (sp.Scene.AttachmentsModule != null) | 1320 | // if (sp.Scene.AttachmentsModule != null) |
1311 | sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); | 1321 | // sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout); |
1312 | } | 1322 | } |
1313 | 1323 | ||
1314 | protected void KillEntity(Scene scene, uint localID) | 1324 | protected void KillEntity(Scene scene, uint localID) |
@@ -1316,6 +1326,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1316 | scene.SendKillObject(new List<uint> { localID }); | 1326 | scene.SendKillObject(new List<uint> { localID }); |
1317 | } | 1327 | } |
1318 | 1328 | ||
1329 | // HG hook | ||
1319 | protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) | 1330 | protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) |
1320 | { | 1331 | { |
1321 | message = null; | 1332 | message = null; |
@@ -1325,7 +1336,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1325 | // This returns 'true' if the new region already has a child agent for our | 1336 | // This returns 'true' if the new region already has a child agent for our |
1326 | // incoming agent. The implication is that, if 'false', we have to create the | 1337 | // incoming agent. The implication is that, if 'false', we have to create the |
1327 | // child and then teleport into the region. | 1338 | // child and then teleport into the region. |
1328 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) | 1339 | protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, |
1340 | int oldsizeX, int oldsizeY, int newsizeX, int newsizeY) | ||
1329 | { | 1341 | { |
1330 | if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) | 1342 | if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
1331 | { | 1343 | { |
@@ -1338,15 +1350,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1338 | 1350 | ||
1339 | return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y); | 1351 | return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y); |
1340 | } | 1352 | } |
1341 | else | 1353 | |
1342 | { | 1354 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, |
1343 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); | 1355 | oldsizeX, oldsizeY, newsizeX, newsizeY); |
1344 | } | ||
1345 | } | 1356 | } |
1346 | 1357 | ||
1347 | protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) | 1358 | // HG Hook |
1359 | protected virtual bool NeedsClosing(GridRegion reg, bool OutViewRange) | ||
1360 | |||
1348 | { | 1361 | { |
1349 | return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); | 1362 | return OutViewRange; |
1350 | } | 1363 | } |
1351 | 1364 | ||
1352 | #endregion | 1365 | #endregion |
@@ -1429,105 +1442,143 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1429 | 1442 | ||
1430 | #region Agent Crossings | 1443 | #region Agent Crossings |
1431 | 1444 | ||
1432 | // Given a position relative to the current region (which has previously been tested to | 1445 | public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, |
1433 | // see that it is actually outside the current region), find the new region that the | 1446 | EntityTransferContext ctx, out string reason) |
1434 | // point is actually in. | 1447 | { |
1435 | // Returns the coordinates and information of the new region or 'null' of it doesn't exist. | 1448 | reason = String.Empty; |
1449 | |||
1450 | UUID agentID = agent.UUID; | ||
1451 | ulong destinyHandle = destiny.RegionHandle; | ||
1452 | |||
1453 | if (m_bannedRegionCache.IfBanned(destinyHandle, agentID)) | ||
1454 | { | ||
1455 | return false; | ||
1456 | } | ||
1457 | |||
1458 | Scene ascene = agent.Scene; | ||
1459 | string homeURI = ascene.GetAgentHomeURI(agentID); | ||
1460 | |||
1461 | |||
1462 | if (!ascene.SimulationService.QueryAccess(destiny, agentID, homeURI, false, position, | ||
1463 | agent.Scene.GetFormatsOffered(), ctx, out reason)) | ||
1464 | { | ||
1465 | m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); | ||
1466 | return false; | ||
1467 | } | ||
1468 | return true; | ||
1469 | } | ||
1470 | |||
1471 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, EntityTransferContext ctx, out Vector3 newpos) | ||
1472 | { | ||
1473 | string r = String.Empty; | ||
1474 | return GetDestination(scene, agentID, pos, ctx, out newpos, out r); | ||
1475 | } | ||
1476 | |||
1477 | // Given a position relative to the current region and outside of it | ||
1478 | // find the new region that the point is actually in. | ||
1479 | // returns 'null' if new region not found or if information | ||
1480 | // and new position relative to it | ||
1481 | // now only works for crossings | ||
1482 | |||
1436 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, | 1483 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, |
1437 | EntityTransferContext ctx, out Vector3 newpos, out string failureReason) | 1484 | EntityTransferContext ctx, out Vector3 newpos, out string failureReason) |
1438 | { | 1485 | { |
1439 | newpos = pos; | 1486 | newpos = pos; |
1440 | failureReason = string.Empty; | 1487 | failureReason = string.Empty; |
1441 | string homeURI = scene.GetAgentHomeURI(agentID); | ||
1442 | 1488 | ||
1443 | // m_log.DebugFormat( | 1489 | // m_log.DebugFormat( |
1444 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); | 1490 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); |
1445 | 1491 | ||
1446 | // Compute world location of the object's position | 1492 | // Compute world location of the agente position |
1447 | double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; | 1493 | double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; |
1448 | double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; | 1494 | double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; |
1449 | 1495 | ||
1450 | // Call the grid service to lookup the region containing the new position. | 1496 | // Call the grid service to lookup the region containing the new position. |
1451 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, | 1497 | GridRegion neighbourRegion = GetRegionContainingWorldLocation( |
1452 | presenceWorldX, presenceWorldY, | 1498 | scene.GridService, scene.RegionInfo.ScopeID, |
1453 | Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); | 1499 | presenceWorldX, presenceWorldY, |
1500 | Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); | ||
1454 | 1501 | ||
1455 | if (neighbourRegion != null) | 1502 | if (neighbourRegion == null) |
1456 | { | 1503 | { |
1457 | // Compute the entity's position relative to the new region | 1504 | return null; |
1458 | newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), | 1505 | } |
1506 | if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) | ||
1507 | { | ||
1508 | return null; | ||
1509 | } | ||
1510 | |||
1511 | m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); | ||
1512 | |||
1513 | // Compute the entity's position relative to the new region | ||
1514 | newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), | ||
1459 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), | 1515 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), |
1460 | pos.Z); | 1516 | pos.Z); |
1461 | 1517 | ||
1462 | if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) | 1518 | string homeURI = scene.GetAgentHomeURI(agentID); |
1463 | { | ||
1464 | failureReason = "Cannot region cross into banned parcel"; | ||
1465 | neighbourRegion = null; | ||
1466 | } | ||
1467 | else | ||
1468 | { | ||
1469 | // If not banned, make sure this agent is not in the list. | ||
1470 | m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); | ||
1471 | } | ||
1472 | 1519 | ||
1473 | // Check to see if we have access to the target region. | 1520 | if (!scene.SimulationService.QueryAccess( |
1474 | if (neighbourRegion != null | 1521 | neighbourRegion, agentID, homeURI, false, newpos, |
1475 | && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason)) | 1522 | scene.GetFormatsOffered(), ctx, out failureReason)) |
1476 | { | ||
1477 | // remember banned | ||
1478 | m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); | ||
1479 | neighbourRegion = null; | ||
1480 | } | ||
1481 | } | ||
1482 | else | ||
1483 | { | 1523 | { |
1484 | // The destination region just doesn't exist | 1524 | // remember the fail |
1485 | failureReason = "Cannot cross into non-existent region"; | 1525 | m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); |
1526 | return null; | ||
1486 | } | 1527 | } |
1487 | 1528 | ||
1488 | if (neighbourRegion == null) | ||
1489 | m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", | ||
1490 | LogHeader, scene.RegionInfo.RegionName, | ||
1491 | scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, | ||
1492 | scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, | ||
1493 | pos); | ||
1494 | else | ||
1495 | m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>", | ||
1496 | LogHeader, neighbourRegion.RegionName, | ||
1497 | neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY, | ||
1498 | newpos.X, newpos.Y); | ||
1499 | |||
1500 | return neighbourRegion; | 1529 | return neighbourRegion; |
1501 | } | 1530 | } |
1502 | 1531 | ||
1503 | public bool Cross(ScenePresence agent, bool isFlying) | 1532 | public bool Cross(ScenePresence agent, bool isFlying) |
1504 | { | 1533 | { |
1534 | agent.IsInTransit = true; | ||
1535 | CrossAsyncDelegate d = CrossAsync; | ||
1536 | d.BeginInvoke(agent, isFlying, CrossCompleted, d); | ||
1537 | return true; | ||
1538 | } | ||
1539 | |||
1540 | private void CrossCompleted(IAsyncResult iar) | ||
1541 | { | ||
1542 | CrossAsyncDelegate icon = (CrossAsyncDelegate)iar.AsyncState; | ||
1543 | ScenePresence agent = icon.EndInvoke(iar); | ||
1544 | |||
1545 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
1546 | |||
1547 | if(!agent.IsChildAgent) | ||
1548 | { | ||
1549 | // crossing failed | ||
1550 | agent.CrossToNewRegionFail(); | ||
1551 | } | ||
1552 | agent.IsInTransit = false; | ||
1553 | } | ||
1554 | |||
1555 | public ScenePresence CrossAsync(ScenePresence agent, bool isFlying) | ||
1556 | { | ||
1557 | uint x; | ||
1558 | uint y; | ||
1505 | Vector3 newpos; | 1559 | Vector3 newpos; |
1506 | EntityTransferContext ctx = new EntityTransferContext(); | 1560 | EntityTransferContext ctx = new EntityTransferContext(); |
1507 | string failureReason; | 1561 | string failureReason; |
1508 | 1562 | ||
1509 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, | 1563 | Vector3 pos = agent.AbsolutePosition + agent.Velocity; |
1564 | |||
1565 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, | ||
1510 | ctx, out newpos, out failureReason); | 1566 | ctx, out newpos, out failureReason); |
1511 | if (neighbourRegion == null) | 1567 | if (neighbourRegion == null) |
1512 | { | 1568 | { |
1513 | agent.ControllingClient.SendAlertMessage(failureReason); | 1569 | if (failureReason != String.Empty) |
1514 | return false; | 1570 | agent.ControllingClient.SendAlertMessage(failureReason); |
1571 | return agent; | ||
1515 | } | 1572 | } |
1516 | 1573 | ||
1517 | agent.IsInTransit = true; | 1574 | // agent.IsInTransit = true; |
1518 | 1575 | ||
1519 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 1576 | CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx); |
1520 | d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, ctx, CrossAgentToNewRegionCompleted, d); | 1577 | agent.IsInTransit = false; |
1521 | 1578 | return agent; | |
1522 | Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion); | ||
1523 | |||
1524 | return true; | ||
1525 | } | 1579 | } |
1526 | 1580 | ||
1527 | 1581 | public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene); | |
1528 | public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, | ||
1529 | Vector3 position, | ||
1530 | Scene initiatingScene); | ||
1531 | 1582 | ||
1532 | private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) | 1583 | private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) |
1533 | { | 1584 | { |
@@ -1628,7 +1679,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1628 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1679 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1629 | } | 1680 | } |
1630 | 1681 | ||
1631 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) | 1682 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx)) |
1632 | { | 1683 | { |
1633 | m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); | 1684 | m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); |
1634 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1685 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
@@ -1644,14 +1695,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1644 | return agent; | 1695 | return agent; |
1645 | } | 1696 | } |
1646 | 1697 | ||
1647 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) | 1698 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx) |
1648 | { | 1699 | { |
1700 | int ts = Util.EnvironmentTickCount(); | ||
1649 | try | 1701 | try |
1650 | { | 1702 | { |
1651 | AgentData cAgent = new AgentData(); | 1703 | AgentData cAgent = new AgentData(); |
1652 | agent.CopyTo(cAgent); | 1704 | agent.CopyTo(cAgent); |
1705 | |||
1706 | // agent.Appearance.WearableCacheItems = null; | ||
1707 | |||
1653 | cAgent.Position = pos; | 1708 | cAgent.Position = pos; |
1654 | 1709 | ||
1710 | cAgent.ChildrenCapSeeds = agent.KnownRegions; | ||
1711 | |||
1655 | if (isFlying) | 1712 | if (isFlying) |
1656 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 1713 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
1657 | 1714 | ||
@@ -1661,7 +1718,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1661 | // Beyond this point, extra cleanup is needed beyond removing transit state | 1718 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1662 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | 1719 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); |
1663 | 1720 | ||
1664 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1721 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) |
1665 | { | 1722 | { |
1666 | // region doesn't take it | 1723 | // region doesn't take it |
1667 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1724 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
@@ -1671,11 +1728,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1671 | neighbourRegion.RegionName, agent.Name); | 1728 | neighbourRegion.RegionName, agent.Name); |
1672 | 1729 | ||
1673 | ReInstantiateScripts(agent); | 1730 | ReInstantiateScripts(agent); |
1674 | agent.AddToPhysicalScene(isFlying); | 1731 | if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero) |
1732 | agent.AddToPhysicalScene(isFlying); | ||
1675 | 1733 | ||
1676 | return false; | 1734 | return false; |
1677 | } | 1735 | } |
1678 | 1736 | ||
1737 | m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts)); | ||
1738 | |||
1679 | } | 1739 | } |
1680 | catch (Exception e) | 1740 | catch (Exception e) |
1681 | { | 1741 | { |
@@ -1693,7 +1753,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1693 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, | 1753 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1694 | bool isFlying, EntityTransferContext ctx) | 1754 | bool isFlying, EntityTransferContext ctx) |
1695 | { | 1755 | { |
1696 | agent.ControllingClient.RequestClientInfo(); | ||
1697 | 1756 | ||
1698 | string agentcaps; | 1757 | string agentcaps; |
1699 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | 1758 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) |
@@ -1704,6 +1763,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1704 | } | 1763 | } |
1705 | 1764 | ||
1706 | // No turning back | 1765 | // No turning back |
1766 | |||
1707 | agent.IsChildAgent = true; | 1767 | agent.IsChildAgent = true; |
1708 | 1768 | ||
1709 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1769 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
@@ -1715,7 +1775,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1715 | if (m_eqModule != null) | 1775 | if (m_eqModule != null) |
1716 | { | 1776 | { |
1717 | m_eqModule.CrossRegion( | 1777 | m_eqModule.CrossRegion( |
1718 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, | 1778 | neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */, |
1719 | neighbourRegion.ExternalEndPoint, | 1779 | neighbourRegion.ExternalEndPoint, |
1720 | capsPath, agent.UUID, agent.ControllingClient.SessionId, | 1780 | capsPath, agent.UUID, agent.ControllingClient.SessionId, |
1721 | neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); | 1781 | neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); |
@@ -1723,25 +1783,36 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1723 | else | 1783 | else |
1724 | { | 1784 | { |
1725 | m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); | 1785 | m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); |
1726 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | 1786 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, |
1727 | capsPath); | 1787 | capsPath); |
1728 | } | 1788 | } |
1729 | 1789 | ||
1790 | /* | ||
1791 | // Backwards compatibility. Best effort | ||
1792 | if (version == 0f) | ||
1793 | { | ||
1794 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1795 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1796 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1797 | } | ||
1798 | */ | ||
1730 | // SUCCESS! | 1799 | // SUCCESS! |
1731 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | 1800 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
1732 | 1801 | ||
1733 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | 1802 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1734 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1803 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1735 | 1804 | ||
1736 | agent.MakeChildAgent(); | 1805 | // this may need the attachments |
1806 | |||
1807 | agent.HasMovedAway(true); | ||
1808 | |||
1809 | agent.MakeChildAgent(neighbourRegion.RegionHandle); | ||
1737 | 1810 | ||
1738 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1811 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1739 | // but not sure yet what the side effects would be. | 1812 | // but not sure yet what the side effects would be. |
1740 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1813 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1741 | 1814 | ||
1742 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1815 | agent.CloseChildAgents(false, neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); |
1743 | agent.SendOtherAgentsAvatarDataToClient(); | ||
1744 | agent.SendOtherAgentsAppearanceToClient(); | ||
1745 | 1816 | ||
1746 | // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6 | 1817 | // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6 |
1747 | /* | 1818 | /* |
@@ -1753,14 +1824,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1753 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | 1824 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
1754 | } | 1825 | } |
1755 | */ | 1826 | */ |
1756 | // Next, let's close the child agent connections that are too far away. | ||
1757 | uint neighbourx; | ||
1758 | uint neighboury; | ||
1759 | Util.RegionHandleToRegionLoc(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1760 | |||
1761 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1762 | |||
1763 | AgentHasMovedAway(agent, false); | ||
1764 | 1827 | ||
1765 | // the user may change their profile information in other region, | 1828 | // the user may change their profile information in other region, |
1766 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 1829 | // so the userinfo in UserProfileCache is not reliable any more, delete it |
@@ -1800,7 +1863,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1800 | #region Enable Child Agent | 1863 | #region Enable Child Agent |
1801 | 1864 | ||
1802 | /// <summary> | 1865 | /// <summary> |
1803 | /// This informs a single neighbouring region about agent "avatar". | 1866 | /// This informs a single neighbouring region about agent "avatar", and avatar about it |
1804 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1867 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1805 | /// </summary> | 1868 | /// </summary> |
1806 | /// <param name="sp"></param> | 1869 | /// <param name="sp"></param> |
@@ -1809,41 +1872,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1809 | { | 1872 | { |
1810 | m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); | 1873 | m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); |
1811 | 1874 | ||
1875 | ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle; | ||
1876 | ulong regionhandler = region.RegionHandle; | ||
1877 | |||
1878 | Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); | ||
1879 | |||
1880 | if (seeds.ContainsKey(regionhandler)) | ||
1881 | seeds.Remove(regionhandler); | ||
1882 | /* | ||
1883 | List<ulong> oldregions = new List<ulong>(seeds.Keys); | ||
1884 | |||
1885 | if (oldregions.Contains(currentRegionHandler)) | ||
1886 | oldregions.Remove(currentRegionHandler); | ||
1887 | */ | ||
1888 | if (!seeds.ContainsKey(currentRegionHandler)) | ||
1889 | seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath); | ||
1890 | |||
1812 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 1891 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
1813 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); | 1892 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); |
1814 | agent.BaseFolder = UUID.Zero; | 1893 | agent.BaseFolder = UUID.Zero; |
1815 | agent.InventoryFolder = UUID.Zero; | 1894 | agent.InventoryFolder = UUID.Zero; |
1816 | agent.startpos = new Vector3(128, 128, 70); | 1895 | agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region); |
1817 | agent.child = true; | 1896 | agent.child = true; |
1818 | agent.Appearance = sp.Appearance; | 1897 | agent.Appearance = new AvatarAppearance(); |
1898 | agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; | ||
1899 | |||
1819 | agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 1900 | agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
1820 | 1901 | ||
1821 | agent.ChildrenCapSeeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); | 1902 | seeds.Add(regionhandler, agent.CapsPath); |
1822 | //m_log.DebugFormat("[XXX] Seeds 1 {0}", agent.ChildrenCapSeeds.Count); | ||
1823 | 1903 | ||
1824 | if (!agent.ChildrenCapSeeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) | ||
1825 | agent.ChildrenCapSeeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath); | ||
1826 | //m_log.DebugFormat("[XXX] Seeds 2 {0}", agent.ChildrenCapSeeds.Count); | ||
1827 | 1904 | ||
1828 | sp.AddNeighbourRegion(region.RegionHandle, agent.CapsPath); | 1905 | // agent.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds); |
1829 | //foreach (ulong h in agent.ChildrenCapSeeds.Keys) | 1906 | agent.ChildrenCapSeeds = null; |
1830 | // m_log.DebugFormat("[XXX] --> {0}", h); | ||
1831 | //m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle); | ||
1832 | if (agent.ChildrenCapSeeds.ContainsKey(region.RegionHandle)) | ||
1833 | { | ||
1834 | m_log.WarnFormat( | ||
1835 | "[ENTITY TRANSFER]: Overwriting caps seed {0} with {1} for region {2} (handle {3}) for {4} in {5}", | ||
1836 | agent.ChildrenCapSeeds[region.RegionHandle], agent.CapsPath, | ||
1837 | region.RegionName, region.RegionHandle, sp.Name, Scene.Name); | ||
1838 | } | ||
1839 | |||
1840 | agent.ChildrenCapSeeds[region.RegionHandle] = agent.CapsPath; | ||
1841 | 1907 | ||
1842 | if (sp.Scene.CapsModule != null) | 1908 | if (sp.Scene.CapsModule != null) |
1843 | { | 1909 | { |
1844 | sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, agent.ChildrenCapSeeds); | 1910 | sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds); |
1845 | } | 1911 | } |
1846 | 1912 | ||
1913 | sp.KnownRegions = seeds; | ||
1914 | sp.AddNeighbourRegionSizeInfo(region); | ||
1915 | |||
1847 | if (currentAgentCircuit != null) | 1916 | if (currentAgentCircuit != null) |
1848 | { | 1917 | { |
1849 | agent.ServiceURLs = currentAgentCircuit.ServiceURLs; | 1918 | agent.ServiceURLs = currentAgentCircuit.ServiceURLs; |
@@ -1853,7 +1922,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1853 | agent.Mac = currentAgentCircuit.Mac; | 1922 | agent.Mac = currentAgentCircuit.Mac; |
1854 | agent.Id0 = currentAgentCircuit.Id0; | 1923 | agent.Id0 = currentAgentCircuit.Id0; |
1855 | } | 1924 | } |
1856 | 1925 | /* | |
1926 | AgentPosition agentpos = null; | ||
1927 | |||
1928 | if (oldregions.Count > 0) | ||
1929 | { | ||
1930 | agentpos = new AgentPosition(); | ||
1931 | agentpos.AgentID = new UUID(sp.UUID.Guid); | ||
1932 | agentpos.SessionID = sp.ControllingClient.SessionId; | ||
1933 | agentpos.Size = sp.Appearance.AvatarSize; | ||
1934 | agentpos.Center = sp.CameraPosition; | ||
1935 | agentpos.Far = sp.DrawDistance; | ||
1936 | agentpos.Position = sp.AbsolutePosition; | ||
1937 | agentpos.Velocity = sp.Velocity; | ||
1938 | agentpos.RegionHandle = currentRegionHandler; | ||
1939 | agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1); | ||
1940 | agentpos.ChildrenCapSeeds = seeds; | ||
1941 | } | ||
1942 | */ | ||
1857 | IPEndPoint external = region.ExternalEndPoint; | 1943 | IPEndPoint external = region.ExternalEndPoint; |
1858 | if (external != null) | 1944 | if (external != null) |
1859 | { | 1945 | { |
@@ -1862,7 +1948,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1862 | InformClientOfNeighbourCompleted, | 1948 | InformClientOfNeighbourCompleted, |
1863 | d); | 1949 | d); |
1864 | } | 1950 | } |
1951 | /* | ||
1952 | if(oldregions.Count >0) | ||
1953 | { | ||
1954 | uint neighbourx; | ||
1955 | uint neighboury; | ||
1956 | UUID scope = sp.Scene.RegionInfo.ScopeID; | ||
1957 | foreach (ulong handler in oldregions) | ||
1958 | { | ||
1959 | // crap code | ||
1960 | Utils.LongToUInts(handler, out neighbourx, out neighboury); | ||
1961 | GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury); | ||
1962 | sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos); | ||
1963 | } | ||
1964 | } | ||
1965 | */ | ||
1865 | } | 1966 | } |
1967 | |||
1866 | #endregion | 1968 | #endregion |
1867 | 1969 | ||
1868 | #region Enable Child Agents | 1970 | #region Enable Child Agents |
@@ -1872,146 +1974,153 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1872 | 1974 | ||
1873 | /// <summary> | 1975 | /// <summary> |
1874 | /// This informs all neighbouring regions about agent "avatar". | 1976 | /// This informs all neighbouring regions about agent "avatar". |
1977 | /// and as important informs the avatar about then | ||
1875 | /// </summary> | 1978 | /// </summary> |
1876 | /// <param name="sp"></param> | 1979 | /// <param name="sp"></param> |
1877 | public void EnableChildAgents(ScenePresence sp) | 1980 | public void EnableChildAgents(ScenePresence sp) |
1878 | { | 1981 | { |
1982 | // assumes that out of view range regions are disconnected by the previus region | ||
1983 | |||
1879 | List<GridRegion> neighbours = new List<GridRegion>(); | 1984 | List<GridRegion> neighbours = new List<GridRegion>(); |
1880 | RegionInfo m_regionInfo = sp.Scene.RegionInfo; | 1985 | Scene spScene = sp.Scene; |
1986 | RegionInfo m_regionInfo = spScene.RegionInfo; | ||
1881 | 1987 | ||
1882 | if (m_regionInfo != null) | 1988 | if (m_regionInfo != null) |
1883 | { | 1989 | { |
1884 | neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); | 1990 | neighbours = GetNeighbors(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); |
1885 | } | 1991 | } |
1886 | else | 1992 | else |
1887 | { | 1993 | { |
1888 | m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); | 1994 | m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); |
1889 | } | 1995 | } |
1890 | 1996 | ||
1891 | /// We need to find the difference between the new regions where there are no child agents | 1997 | ulong currentRegionHandler = m_regionInfo.RegionHandle; |
1892 | /// and the regions where there are already child agents. We only send notification to the former. | ||
1893 | List<ulong> neighbourHandles = NeighbourHandles(neighbours); // on this region | ||
1894 | neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too | ||
1895 | List<ulong> previousRegionNeighbourHandles; | ||
1896 | 1998 | ||
1897 | if (sp.Scene.CapsModule != null) | 1999 | LinkedList<ulong> previousRegionNeighbourHandles; |
2000 | Dictionary<ulong, string> seeds; | ||
2001 | ICapabilitiesModule capsModule = spScene.CapsModule; | ||
2002 | |||
2003 | if (capsModule != null) | ||
1898 | { | 2004 | { |
1899 | previousRegionNeighbourHandles = | 2005 | seeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(sp.UUID)); |
1900 | new List<ulong>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys); | 2006 | previousRegionNeighbourHandles = new LinkedList<ulong>(seeds.Keys); |
1901 | } | 2007 | } |
1902 | else | 2008 | else |
1903 | { | 2009 | { |
1904 | previousRegionNeighbourHandles = new List<ulong>(); | 2010 | seeds = new Dictionary<ulong, string>(); |
2011 | previousRegionNeighbourHandles = new LinkedList<ulong>(); | ||
1905 | } | 2012 | } |
1906 | 2013 | ||
1907 | List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); | 2014 | IClientAPI spClient = sp.ControllingClient; |
1908 | List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); | ||
1909 | |||
1910 | // Dump("Current Neighbors", neighbourHandles); | ||
1911 | // Dump("Previous Neighbours", previousRegionNeighbourHandles); | ||
1912 | // Dump("New Neighbours", newRegions); | ||
1913 | // Dump("Old Neighbours", oldRegions); | ||
1914 | 2015 | ||
1915 | /// Update the scene presence's known regions here on this region | 2016 | if (!seeds.ContainsKey(currentRegionHandler)) |
1916 | sp.DropOldNeighbours(oldRegions); | 2017 | seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath); |
1917 | |||
1918 | /// Collect as many seeds as possible | ||
1919 | Dictionary<ulong, string> seeds; | ||
1920 | if (sp.Scene.CapsModule != null) | ||
1921 | seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); | ||
1922 | else | ||
1923 | seeds = new Dictionary<ulong, string>(); | ||
1924 | 2018 | ||
1925 | //m_log.Debug(" !!! No. of seeds: " + seeds.Count); | 2019 | AgentCircuitData currentAgentCircuit = |
1926 | if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) | 2020 | spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
1927 | seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath); | ||
1928 | 2021 | ||
1929 | /// Create the necessary child agents | ||
1930 | List<AgentCircuitData> cagents = new List<AgentCircuitData>(); | 2022 | List<AgentCircuitData> cagents = new List<AgentCircuitData>(); |
2023 | List<ulong> newneighbours = new List<ulong>(); | ||
2024 | |||
1931 | foreach (GridRegion neighbour in neighbours) | 2025 | foreach (GridRegion neighbour in neighbours) |
1932 | { | 2026 | { |
1933 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) | 2027 | ulong handler = neighbour.RegionHandle; |
2028 | |||
2029 | if (previousRegionNeighbourHandles.Contains(handler)) | ||
1934 | { | 2030 | { |
1935 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 2031 | // agent already knows this region |
1936 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); | 2032 | previousRegionNeighbourHandles.Remove(handler); |
1937 | agent.BaseFolder = UUID.Zero; | 2033 | continue; |
1938 | agent.InventoryFolder = UUID.Zero; | 2034 | } |
1939 | agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour); | ||
1940 | agent.child = true; | ||
1941 | agent.Appearance = sp.Appearance; | ||
1942 | if (currentAgentCircuit != null) | ||
1943 | { | ||
1944 | agent.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
1945 | agent.IPAddress = currentAgentCircuit.IPAddress; | ||
1946 | agent.Viewer = currentAgentCircuit.Viewer; | ||
1947 | agent.Channel = currentAgentCircuit.Channel; | ||
1948 | agent.Mac = currentAgentCircuit.Mac; | ||
1949 | agent.Id0 = currentAgentCircuit.Id0; | ||
1950 | } | ||
1951 | 2035 | ||
1952 | if (newRegions.Contains(neighbour.RegionHandle)) | 2036 | if (handler == currentRegionHandler) |
1953 | { | 2037 | continue; |
1954 | agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 2038 | |
1955 | sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); | 2039 | // a new region to add |
1956 | seeds.Add(neighbour.RegionHandle, agent.CapsPath); | 2040 | AgentCircuitData agent = spClient.RequestClientInfo(); |
1957 | } | 2041 | agent.BaseFolder = UUID.Zero; |
1958 | else | 2042 | agent.InventoryFolder = UUID.Zero; |
1959 | { | 2043 | agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour); |
1960 | agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); | 2044 | agent.child = true; |
1961 | } | 2045 | agent.Appearance = new AvatarAppearance(); |
2046 | agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; | ||
1962 | 2047 | ||
1963 | cagents.Add(agent); | 2048 | if (currentAgentCircuit != null) |
2049 | { | ||
2050 | agent.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
2051 | agent.IPAddress = currentAgentCircuit.IPAddress; | ||
2052 | agent.Viewer = currentAgentCircuit.Viewer; | ||
2053 | agent.Channel = currentAgentCircuit.Channel; | ||
2054 | agent.Mac = currentAgentCircuit.Mac; | ||
2055 | agent.Id0 = currentAgentCircuit.Id0; | ||
1964 | } | 2056 | } |
1965 | } | ||
1966 | 2057 | ||
1967 | /// Update all child agent with everyone's seeds | 2058 | newneighbours.Add(handler); |
1968 | foreach (AgentCircuitData a in cagents) | 2059 | agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
1969 | { | 2060 | seeds.Add(handler, agent.CapsPath); |
1970 | a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds); | ||
1971 | } | ||
1972 | 2061 | ||
1973 | if (sp.Scene.CapsModule != null) | 2062 | agent.ChildrenCapSeeds = null; |
1974 | { | 2063 | cagents.Add(agent); |
1975 | sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds); | ||
1976 | } | 2064 | } |
1977 | sp.KnownRegions = seeds; | ||
1978 | //avatar.Scene.DumpChildrenSeeds(avatar.UUID); | ||
1979 | //avatar.DumpKnownRegions(); | ||
1980 | 2065 | ||
1981 | bool newAgent = false; | 2066 | if (previousRegionNeighbourHandles.Contains(currentRegionHandler)) |
1982 | int count = 0; | 2067 | previousRegionNeighbourHandles.Remove(currentRegionHandler); |
1983 | foreach (GridRegion neighbour in neighbours) | 2068 | |
1984 | { | 2069 | // previousRegionNeighbourHandles now contains regions to forget |
1985 | //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName); | 2070 | foreach (ulong handler in previousRegionNeighbourHandles) |
1986 | // Don't do it if there's already an agent in that region | 2071 | seeds.Remove(handler); |
1987 | if (newRegions.Contains(neighbour.RegionHandle)) | 2072 | |
1988 | newAgent = true; | 2073 | /// Update all child agent with everyone's seeds |
1989 | else | 2074 | // foreach (AgentCircuitData a in cagents) |
1990 | newAgent = false; | 2075 | // a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds); |
1991 | // continue; | 2076 | |
2077 | if (capsModule != null) | ||
2078 | capsModule.SetChildrenSeed(sp.UUID, seeds); | ||
1992 | 2079 | ||
1993 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) | 2080 | sp.KnownRegions = seeds; |
2081 | sp.SetNeighbourRegionSizeInfo(neighbours); | ||
2082 | |||
2083 | AgentPosition agentpos = new AgentPosition(); | ||
2084 | agentpos.AgentID = new UUID(sp.UUID.Guid); | ||
2085 | agentpos.SessionID = spClient.SessionId; | ||
2086 | agentpos.Size = sp.Appearance.AvatarSize; | ||
2087 | agentpos.Center = sp.CameraPosition; | ||
2088 | agentpos.Far = sp.DrawDistance; | ||
2089 | agentpos.Position = sp.AbsolutePosition; | ||
2090 | agentpos.Velocity = sp.Velocity; | ||
2091 | agentpos.RegionHandle = currentRegionHandler; | ||
2092 | agentpos.Throttles = spClient.GetThrottlesPacked(1); | ||
2093 | // agentpos.ChildrenCapSeeds = seeds; | ||
2094 | |||
2095 | Util.FireAndForget(delegate | ||
2096 | { | ||
2097 | Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start | ||
2098 | int count = 0; | ||
2099 | |||
2100 | foreach (GridRegion neighbour in neighbours) | ||
1994 | { | 2101 | { |
2102 | ulong handler = neighbour.RegionHandle; | ||
1995 | try | 2103 | try |
1996 | { | 2104 | { |
1997 | // Let's put this back at sync, so that it doesn't clog | 2105 | if (newneighbours.Contains(handler)) |
1998 | // the network, especially for regions in the same physical server. | 2106 | { |
1999 | // We're really not in a hurry here. | 2107 | InformClientOfNeighbourAsync(sp, cagents[count], neighbour, |
2000 | InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent); | 2108 | neighbour.ExternalEndPoint, true); |
2001 | //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 2109 | count++; |
2002 | //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, | 2110 | } |
2003 | // InformClientOfNeighbourCompleted, | 2111 | else if (!previousRegionNeighbourHandles.Contains(handler)) |
2004 | // d); | 2112 | { |
2113 | spScene.SimulationService.UpdateAgent(neighbour, agentpos); | ||
2114 | } | ||
2005 | } | 2115 | } |
2006 | |||
2007 | catch (ArgumentOutOfRangeException) | 2116 | catch (ArgumentOutOfRangeException) |
2008 | { | 2117 | { |
2009 | m_log.ErrorFormat( | 2118 | m_log.ErrorFormat( |
2010 | "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", | 2119 | "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", |
2011 | neighbour.ExternalHostName, | 2120 | neighbour.ExternalHostName, |
2012 | neighbour.RegionHandle, | 2121 | neighbour.RegionHandle, |
2013 | neighbour.RegionLocX, | 2122 | neighbour.RegionLocX, |
2014 | neighbour.RegionLocY); | 2123 | neighbour.RegionLocY); |
2015 | } | 2124 | } |
2016 | catch (Exception e) | 2125 | catch (Exception e) |
2017 | { | 2126 | { |
@@ -2028,11 +2137,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2028 | 2137 | ||
2029 | // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. | 2138 | // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. |
2030 | // throw e; | 2139 | // throw e; |
2031 | |||
2032 | } | 2140 | } |
2033 | } | 2141 | } |
2034 | count++; | 2142 | }); |
2035 | } | ||
2036 | } | 2143 | } |
2037 | 2144 | ||
2038 | // Computes the difference between two region bases. | 2145 | // Computes the difference between two region bases. |
@@ -2040,26 +2147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2040 | // The first region is the home region of the passed scene presence. | 2147 | // The first region is the home region of the passed scene presence. |
2041 | Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) | 2148 | Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) |
2042 | { | 2149 | { |
2043 | /* | 2150 | return new Vector3(sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX, |
2044 | int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX; | ||
2045 | int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY; | ||
2046 | int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize; | ||
2047 | int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize; | ||
2048 | int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize; | ||
2049 | int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize; | ||
2050 | return new Vector3(shiftx, shifty, 0f); | ||
2051 | */ | ||
2052 | return new Vector3( sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX, | ||
2053 | sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, | 2151 | sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, |
2054 | 0f); | 2152 | 0f); |
2055 | } | 2153 | } |
2056 | 2154 | ||
2057 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) | ||
2058 | { | ||
2059 | // Since we don't know how big the regions could be, we have to search a very large area | ||
2060 | // to find possible regions. | ||
2061 | return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize); | ||
2062 | } | ||
2063 | 2155 | ||
2064 | #region NotFoundLocationCache class | 2156 | #region NotFoundLocationCache class |
2065 | // A collection of not found locations to make future lookups 'not found' lookups quick. | 2157 | // A collection of not found locations to make future lookups 'not found' lookups quick. |
@@ -2144,7 +2236,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2144 | #endregion // NotFoundLocationCache class | 2236 | #endregion // NotFoundLocationCache class |
2145 | private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); | 2237 | private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); |
2146 | 2238 | ||
2147 | // Given a world position (fractional meter coordinate), get the GridRegion info for | 2239 | // needed for current OSG or old grid code |
2240 | |||
2241 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) | ||
2242 | { | ||
2243 | // Since we don't know how big the regions could be, we have to search a very large area | ||
2244 | // to find possible regions. | ||
2245 | return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize); | ||
2246 | } | ||
2247 | |||
2248 | // Given a world position, get the GridRegion info for | ||
2148 | // the region containing that point. | 2249 | // the region containing that point. |
2149 | // Someday this should be a method on GridService. | 2250 | // Someday this should be a method on GridService. |
2150 | // 'pSizeHint' is the size of the source region but since the destination point can be anywhere | 2251 | // 'pSizeHint' is the size of the source region but since the destination point can be anywhere |
@@ -2153,7 +2254,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2153 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, | 2254 | public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, |
2154 | double px, double py, uint pSizeHint) | 2255 | double px, double py, uint pSizeHint) |
2155 | { | 2256 | { |
2156 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: query, loc=<{1},{2}>", LogHeader, px, py); | 2257 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); |
2157 | GridRegion ret = null; | 2258 | GridRegion ret = null; |
2158 | const double fudge = 2.0; | 2259 | const double fudge = 2.0; |
2159 | 2260 | ||
@@ -2164,7 +2265,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2164 | // thus re-ask the GridService about the location. | 2265 | // thus re-ask the GridService about the location. |
2165 | if (m_notFoundLocationCache.Contains(px, py)) | 2266 | if (m_notFoundLocationCache.Contains(px, py)) |
2166 | { | 2267 | { |
2167 | m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); | 2268 | // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); |
2168 | return null; | 2269 | return null; |
2169 | } | 2270 | } |
2170 | 2271 | ||
@@ -2246,55 +2347,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2246 | private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, | 2347 | private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, |
2247 | IPEndPoint endPoint, bool newAgent) | 2348 | IPEndPoint endPoint, bool newAgent) |
2248 | { | 2349 | { |
2249 | // Let's wait just a little to give time to originating regions to catch up with closing child agents | ||
2250 | // after a cross here | ||
2251 | Thread.Sleep(500); | ||
2252 | 2350 | ||
2253 | Scene scene = sp.Scene; | 2351 | if (newAgent) |
2254 | 2352 | { | |
2255 | m_log.DebugFormat( | 2353 | Scene scene = sp.Scene; |
2256 | "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", | ||
2257 | sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); | ||
2258 | 2354 | ||
2259 | string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); | 2355 | m_log.DebugFormat( |
2356 | "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", | ||
2357 | sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); | ||
2260 | 2358 | ||
2261 | string reason = String.Empty; | 2359 | string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); |
2262 | 2360 | ||
2263 | bool regionAccepted = scene.SimulationService.CreateAgent(null, reg, a, (uint)TeleportFlags.Default, out reason); | 2361 | string reason = String.Empty; |
2264 | 2362 | ||
2265 | if (regionAccepted && newAgent) | 2363 | EntityTransferContext ctx = new EntityTransferContext(); |
2266 | { | 2364 | bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, a, (uint)TeleportFlags.Default, ctx, out reason); |
2267 | if (m_eqModule != null) | 2365 | |
2366 | if (regionAccepted) | ||
2268 | { | 2367 | { |
2269 | #region IP Translation for NAT | 2368 | // give time for createAgent to finish, since it is async and does grid services access |
2270 | IClientIPEndpoint ipepClient; | 2369 | Thread.Sleep(500); |
2271 | if (sp.ClientView.TryGet(out ipepClient)) | 2370 | |
2371 | if (m_eqModule != null) | ||
2272 | { | 2372 | { |
2273 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | 2373 | #region IP Translation for NAT |
2274 | } | 2374 | IClientIPEndpoint ipepClient; |
2275 | #endregion | 2375 | if (sp.ClientView.TryGet(out ipepClient)) |
2376 | { | ||
2377 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
2378 | } | ||
2379 | #endregion | ||
2276 | 2380 | ||
2277 | m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + | 2381 | m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + |
2278 | "and EstablishAgentCommunication with seed cap {8}", LogHeader, | 2382 | "and EstablishAgentCommunication with seed cap {8}", LogHeader, |
2279 | scene.RegionInfo.RegionName, sp.Name, | 2383 | scene.RegionInfo.RegionName, sp.Name, |
2280 | reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath); | 2384 | reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY, capsPath); |
2281 | 2385 | ||
2282 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY); | 2386 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY); |
2283 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY); | 2387 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY); |
2284 | } | 2388 | } |
2285 | else | 2389 | else |
2286 | { | 2390 | { |
2287 | sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); | 2391 | sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); |
2288 | // TODO: make Event Queue disablable! | 2392 | // TODO: make Event Queue disablable! |
2393 | } | ||
2394 | |||
2395 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint); | ||
2289 | } | 2396 | } |
2290 | 2397 | ||
2291 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint); | 2398 | if (!regionAccepted) |
2399 | m_log.WarnFormat( | ||
2400 | "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}", | ||
2401 | reg.RegionName, sp.Name, sp.UUID, reason); | ||
2292 | } | 2402 | } |
2293 | 2403 | ||
2294 | if (!regionAccepted) | ||
2295 | m_log.WarnFormat( | ||
2296 | "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}", | ||
2297 | reg.RegionName, sp.Name, sp.UUID, reason); | ||
2298 | } | 2404 | } |
2299 | 2405 | ||
2300 | /// <summary> | 2406 | /// <summary> |
@@ -2327,7 +2433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2327 | /// <param name="pRegionLocX"></param> | 2433 | /// <param name="pRegionLocX"></param> |
2328 | /// <param name="pRegionLocY"></param> | 2434 | /// <param name="pRegionLocY"></param> |
2329 | /// <returns></returns> | 2435 | /// <returns></returns> |
2330 | protected List<GridRegion> GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) | 2436 | protected List<GridRegion> GetNeighbors(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) |
2331 | { | 2437 | { |
2332 | Scene pScene = avatar.Scene; | 2438 | Scene pScene = avatar.Scene; |
2333 | RegionInfo m_regionInfo = pScene.RegionInfo; | 2439 | RegionInfo m_regionInfo = pScene.RegionInfo; |
@@ -2338,18 +2444,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2338 | // view to include everything in the megaregion | 2444 | // view to include everything in the megaregion |
2339 | if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) | 2445 | if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) |
2340 | { | 2446 | { |
2341 | // The area to check is as big as the current region. | 2447 | uint dd = (uint)avatar.DrawDistance; |
2342 | // We presume all adjacent regions are the same size as this region. | ||
2343 | uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance, | ||
2344 | Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY)); | ||
2345 | 2448 | ||
2346 | uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; | 2449 | // until avatar movement updates client connections, we need to seend at least this current region imediate Neighbors |
2347 | uint startY = Util.RegionToWorldLoc(pRegionLocY) - dd + Constants.RegionSize/2; | 2450 | uint ddX = Math.Max(dd, Constants.RegionSize); |
2451 | uint ddY = Math.Max(dd, Constants.RegionSize); | ||
2348 | 2452 | ||
2349 | uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2; | 2453 | ddX--; |
2350 | uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2; | 2454 | ddY--; |
2351 | 2455 | ||
2352 | neighbours | 2456 | // reference to region edges. Should be avatar position |
2457 | uint startX = Util.RegionToWorldLoc(pRegionLocX); | ||
2458 | uint endX = startX + m_regionInfo.RegionSizeX; | ||
2459 | uint startY = Util.RegionToWorldLoc(pRegionLocY); | ||
2460 | uint endY = startY + m_regionInfo.RegionSizeY; | ||
2461 | |||
2462 | startX -= ddX; | ||
2463 | startY -= ddY; | ||
2464 | endX += ddX; | ||
2465 | endY += ddY; | ||
2466 | |||
2467 | neighbours | ||
2353 | = avatar.Scene.GridService.GetRegionRange( | 2468 | = avatar.Scene.GridService.GetRegionRange( |
2354 | m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); | 2469 | m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); |
2355 | } | 2470 | } |
@@ -2365,72 +2480,70 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2365 | (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y)); | 2480 | (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y)); |
2366 | } | 2481 | } |
2367 | 2482 | ||
2368 | // neighbours.ForEach( | ||
2369 | // n => | ||
2370 | // m_log.DebugFormat( | ||
2371 | // "[ENTITY TRANSFER MODULE]: Region flags for {0} as seen by {1} are {2}", | ||
2372 | // n.RegionName, Scene.Name, n.RegionFlags != null ? n.RegionFlags.ToString() : "not present")); | ||
2373 | |||
2374 | // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). | 2483 | // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). |
2375 | neighbours.RemoveAll( | 2484 | neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID ); |
2376 | r => | ||
2377 | r.RegionID == m_regionInfo.RegionID | ||
2378 | || (r.RegionFlags != null && (r.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0)); | ||
2379 | 2485 | ||
2380 | return neighbours; | 2486 | return neighbours; |
2381 | } | 2487 | } |
2488 | #endregion | ||
2489 | |||
2490 | #region Agent Arrived | ||
2382 | 2491 | ||
2383 | private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) | 2492 | public void AgentArrivedAtDestination(UUID id) |
2384 | { | 2493 | { |
2385 | return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); }); | 2494 | m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); |
2386 | } | 2495 | } |
2387 | 2496 | ||
2388 | // private List<ulong> CommonNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) | 2497 | #endregion |
2389 | // { | ||
2390 | // return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); }); | ||
2391 | // } | ||
2392 | 2498 | ||
2393 | private List<ulong> OldNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) | 2499 | #region Object Transfers |
2394 | { | ||
2395 | return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); }); | ||
2396 | } | ||
2397 | 2500 | ||
2398 | private List<ulong> NeighbourHandles(List<GridRegion> neighbours) | 2501 | public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos) |
2399 | { | 2502 | { |
2400 | List<ulong> handles = new List<ulong>(); | 2503 | newpos = targetPosition; |
2401 | foreach (GridRegion reg in neighbours) | 2504 | |
2505 | Scene scene = grp.Scene; | ||
2506 | if (scene == null) | ||
2507 | return null; | ||
2508 | |||
2509 | int x = (int)targetPosition.X + (int)scene.RegionInfo.WorldLocX; | ||
2510 | if (targetPosition.X >= 0) | ||
2511 | x++; | ||
2512 | else | ||
2513 | x--; | ||
2514 | |||
2515 | int y = (int)targetPosition.Y + (int)scene.RegionInfo.WorldLocY; | ||
2516 | if (targetPosition.Y >= 0) | ||
2517 | y++; | ||
2518 | else | ||
2519 | y--; | ||
2520 | |||
2521 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID,x,y); | ||
2522 | if (neighbourRegion == null) | ||
2402 | { | 2523 | { |
2403 | handles.Add(reg.RegionHandle); | 2524 | return null; |
2404 | } | 2525 | } |
2405 | return handles; | ||
2406 | } | ||
2407 | 2526 | ||
2408 | // private void Dump(string msg, List<ulong> handles) | 2527 | float newRegionSizeX = neighbourRegion.RegionSizeX; |
2409 | // { | 2528 | float newRegionSizeY = neighbourRegion.RegionSizeY; |
2410 | // m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); | 2529 | if (newRegionSizeX == 0) |
2411 | // foreach (ulong handle in handles) | 2530 | newRegionSizeX = Constants.RegionSize; |
2412 | // { | 2531 | if (newRegionSizeY == 0) |
2413 | // uint x, y; | 2532 | newRegionSizeY = Constants.RegionSize; |
2414 | // Utils.LongToUInts(handle, out x, out y); | ||
2415 | // x = x / Constants.RegionSize; | ||
2416 | // y = y / Constants.RegionSize; | ||
2417 | // m_log.InfoFormat("({0}, {1})", x, y); | ||
2418 | // } | ||
2419 | // } | ||
2420 | 2533 | ||
2421 | #endregion | ||
2422 | 2534 | ||
2423 | #region Agent Arrived | 2535 | newpos.X = targetPosition.X - (neighbourRegion.RegionLocX - (int)scene.RegionInfo.WorldLocX); |
2536 | newpos.Y = targetPosition.Y - (neighbourRegion.RegionLocY - (int)scene.RegionInfo.WorldLocY); | ||
2424 | 2537 | ||
2425 | public void AgentArrivedAtDestination(UUID id) | ||
2426 | { | ||
2427 | m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); | ||
2428 | } | ||
2429 | 2538 | ||
2430 | #endregion | 2539 | const float enterDistance = 0.2f; |
2540 | newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance); | ||
2541 | newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance); | ||
2431 | 2542 | ||
2432 | #region Object Transfers | 2543 | return neighbourRegion; |
2544 | } | ||
2433 | 2545 | ||
2546 | /* not in use. -> CrossPrimGroupIntoNewRegion | ||
2434 | /// <summary> | 2547 | /// <summary> |
2435 | /// Move the given scene object into a new region depending on which region its absolute position has moved | 2548 | /// Move the given scene object into a new region depending on which region its absolute position has moved |
2436 | /// into. | 2549 | /// into. |
@@ -2453,20 +2566,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2453 | if (scene == null) | 2566 | if (scene == null) |
2454 | return; | 2567 | return; |
2455 | 2568 | ||
2456 | if (grp.RootPart.DIE_AT_EDGE) | ||
2457 | { | ||
2458 | // We remove the object here | ||
2459 | try | ||
2460 | { | ||
2461 | scene.DeleteSceneObject(grp, false); | ||
2462 | } | ||
2463 | catch (Exception) | ||
2464 | { | ||
2465 | m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); | ||
2466 | } | ||
2467 | return; | ||
2468 | } | ||
2469 | |||
2470 | // Remember the old group position in case the region lookup fails so position can be restored. | 2569 | // Remember the old group position in case the region lookup fails so position can be restored. |
2471 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; | 2570 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; |
2472 | 2571 | ||
@@ -2509,7 +2608,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2509 | grp.ScheduleGroupForFullUpdate(); | 2608 | grp.ScheduleGroupForFullUpdate(); |
2510 | } | 2609 | } |
2511 | } | 2610 | } |
2512 | 2611 | */ | |
2513 | /// <summary> | 2612 | /// <summary> |
2514 | /// Move the given scene object into a new region | 2613 | /// Move the given scene object into a new region |
2515 | /// </summary> | 2614 | /// </summary> |
@@ -2519,7 +2618,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2519 | /// true if the crossing itself was successful, false on failure | 2618 | /// true if the crossing itself was successful, false on failure |
2520 | /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region | 2619 | /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region |
2521 | /// </returns> | 2620 | /// </returns> |
2522 | protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent) | 2621 | public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent, bool removeScripts) |
2523 | { | 2622 | { |
2524 | //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); | 2623 | //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); |
2525 | 2624 | ||
@@ -2551,7 +2650,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2551 | // We remove the object here | 2650 | // We remove the object here |
2552 | try | 2651 | try |
2553 | { | 2652 | { |
2554 | grp.Scene.DeleteSceneObject(grp, silent); | 2653 | grp.Scene.DeleteSceneObject(grp, silent, removeScripts); |
2555 | } | 2654 | } |
2556 | catch (Exception e) | 2655 | catch (Exception e) |
2557 | { | 2656 | { |
@@ -2560,30 +2659,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2560 | grp, e); | 2659 | grp, e); |
2561 | } | 2660 | } |
2562 | } | 2661 | } |
2563 | /* | ||
2564 | * done on caller ( not in attachments crossing for now) | ||
2565 | else | ||
2566 | { | ||
2567 | |||
2568 | if (!grp.IsDeleted) | ||
2569 | { | ||
2570 | PhysicsActor pa = grp.RootPart.PhysActor; | ||
2571 | if (pa != null) | ||
2572 | { | ||
2573 | pa.CrossingFailure(); | ||
2574 | if (grp.RootPart.KeyframeMotion != null) | ||
2575 | { | ||
2576 | // moved to KeyframeMotion.CrossingFailure | ||
2577 | // grp.RootPart.Velocity = Vector3.Zero; | ||
2578 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
2579 | // grp.SendGroupRootTerseUpdate(); | ||
2580 | } | ||
2581 | } | ||
2582 | } | ||
2583 | |||
2584 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | ||
2585 | } | ||
2586 | */ | ||
2587 | } | 2662 | } |
2588 | else | 2663 | else |
2589 | { | 2664 | { |
@@ -2625,7 +2700,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2625 | "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", | 2700 | "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", |
2626 | clone.UUID, destination.RegionName); | 2701 | clone.UUID, destination.RegionName); |
2627 | 2702 | ||
2628 | CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent); | 2703 | CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent,true); |
2629 | } | 2704 | } |
2630 | } | 2705 | } |
2631 | 2706 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs index a3109e0..e3c6c0d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | |||
@@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
299 | id, m_mod.Scene.RegionInfo.RegionName, currentState)); | 299 | id, m_mod.Scene.RegionInfo.RegionName, currentState)); |
300 | } | 300 | } |
301 | 301 | ||
302 | int count = 200; | 302 | int count = 400; |
303 | 303 | ||
304 | // There should be no race condition here since no other code should be removing the agent transfer or | 304 | // There should be no race condition here since no other code should be removing the agent transfer or |
305 | // changing the state to another other than Transferring => ReceivedAtDestination. | 305 | // changing the state to another other than Transferring => ReceivedAtDestination. |
@@ -354,4 +354,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
354 | } | 354 | } |
355 | } | 355 | } |
356 | } | 356 | } |
357 | } \ No newline at end of file | 357 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index fa23590..1783e0a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -239,13 +239,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
239 | return region; | 239 | return region; |
240 | } | 240 | } |
241 | 241 | ||
242 | protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) | 242 | protected override bool NeedsClosing(GridRegion reg, bool OutViewRange) |
243 | { | 243 | { |
244 | if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 244 | if (OutViewRange) |
245 | return true; | 245 | return true; |
246 | 246 | ||
247 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); | 247 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); |
248 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) | 248 | if (flags == -1 || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) |
249 | return true; | 249 | return true; |
250 | 250 | ||
251 | return false; | 251 | return false; |
@@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
266 | protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 266 | protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout) |
267 | { | 267 | { |
268 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); | 268 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); |
269 | reason = string.Empty; | 269 | reason = string.Empty; |
@@ -308,7 +308,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
311 | return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); | 311 | return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout); |
312 | } | ||
313 | |||
314 | public void TriggerTeleportHome(UUID id, IClientAPI client) | ||
315 | { | ||
316 | TeleportHome(id, client); | ||
312 | } | 317 | } |
313 | 318 | ||
314 | protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) | 319 | protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) |
@@ -328,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
328 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance"); | 333 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance"); |
329 | 334 | ||
330 | // Check wearables | 335 | // Check wearables |
331 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) | 336 | for (int i = 0; i < sp.Appearance.Wearables.Length ; i++) |
332 | { | 337 | { |
333 | for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++) | 338 | for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++) |
334 | { | 339 | { |
@@ -337,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
337 | 342 | ||
338 | bool found = false; | 343 | bool found = false; |
339 | foreach (AvatarAppearance a in ExportedAppearance) | 344 | foreach (AvatarAppearance a in ExportedAppearance) |
340 | if (a.Wearables[i] != null) | 345 | if (i < a.Wearables.Length && a.Wearables[i] != null) |
341 | { | 346 | { |
342 | found = true; | 347 | found = true; |
343 | break; | 348 | break; |
@@ -351,7 +356,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
351 | 356 | ||
352 | found = false; | 357 | found = false; |
353 | foreach (AvatarAppearance a in ExportedAppearance) | 358 | foreach (AvatarAppearance a in ExportedAppearance) |
354 | if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID) | 359 | if (i < a.Wearables.Length && sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID) |
355 | { | 360 | { |
356 | found = true; | 361 | found = true; |
357 | break; | 362 | break; |
@@ -429,10 +434,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
429 | // return base.UpdateAgent(reg, finalDestination, agentData, sp); | 434 | // return base.UpdateAgent(reg, finalDestination, agentData, sp); |
430 | //} | 435 | //} |
431 | 436 | ||
432 | public override void TriggerTeleportHome(UUID id, IClientAPI client) | ||
433 | { | ||
434 | TeleportHome(id, client); | ||
435 | } | ||
436 | 437 | ||
437 | public override bool TeleportHome(UUID id, IClientAPI client) | 438 | public override bool TeleportHome(UUID id, IClientAPI client) |
438 | { | 439 | { |
@@ -491,9 +492,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
491 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", | 492 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", |
492 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); | 493 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); |
493 | 494 | ||
494 | DoTeleport( | 495 | DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); |
495 | sp, homeGatekeeper, finalDestination, | ||
496 | position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); | ||
497 | return true; | 496 | return true; |
498 | } | 497 | } |
499 | 498 | ||
@@ -760,4 +759,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
760 | return region; | 759 | return region; |
761 | } | 760 | } |
762 | } | 761 | } |
763 | } \ No newline at end of file | 762 | } |