diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 426 |
1 files changed, 210 insertions, 216 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 3cb1901..7e72d47 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
148 | 148 | ||
149 | protected virtual void OnNewClient(IClientAPI client) | 149 | protected virtual void OnNewClient(IClientAPI client) |
150 | { | 150 | { |
151 | client.OnTeleportHomeRequest += TeleportHome; | 151 | client.OnTeleportHomeRequest += TriggerTeleportHome; |
152 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 152 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
153 | } | 153 | } |
154 | 154 | ||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
222 | /// <param name="sp"></param> | 222 | /// <param name="sp"></param> |
223 | /// <param name="position"></param> | 223 | /// <param name="position"></param> |
224 | /// <param name="lookAt"></param> | 224 | /// <param name="lookAt"></param> |
225 | /// <param name="teleportFlags"></param | 225 | /// <param name="teleportFlags"></param> |
226 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | 226 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) |
227 | { | 227 | { |
228 | m_log.DebugFormat( | 228 | m_log.DebugFormat( |
@@ -266,11 +266,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
266 | position.Z = newPosZ; | 266 | position.Z = newPosZ; |
267 | } | 267 | } |
268 | 268 | ||
269 | if (sp.Flying) | ||
270 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
271 | |||
269 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 272 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
270 | 273 | ||
271 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 274 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
272 | 275 | ||
273 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 276 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
277 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | ||
274 | sp.Velocity = Vector3.Zero; | 278 | sp.Velocity = Vector3.Zero; |
275 | sp.Teleport(position); | 279 | sp.Teleport(position); |
276 | 280 | ||
@@ -446,8 +450,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
446 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 450 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
447 | // it's actually doing a lot of work. | 451 | // it's actually doing a lot of work. |
448 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 452 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
449 | 453 | if (endPoint == null || endPoint.Address == null) | |
450 | if (endPoint.Address == null) | ||
451 | { | 454 | { |
452 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 455 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
453 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | 456 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
@@ -487,6 +490,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
487 | // both regions | 490 | // both regions |
488 | if (sp.ParentID != (uint)0) | 491 | if (sp.ParentID != (uint)0) |
489 | sp.StandUp(); | 492 | sp.StandUp(); |
493 | else if (sp.Flying) | ||
494 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
490 | 495 | ||
491 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to | 496 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to |
492 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). | 497 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). |
@@ -664,7 +669,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
664 | // | 669 | // |
665 | // This sleep can be increased if necessary. However, whilst it's active, | 670 | // This sleep can be increased if necessary. However, whilst it's active, |
666 | // an agent cannot teleport back to this region if it has teleported away. | 671 | // an agent cannot teleport back to this region if it has teleported away. |
667 | Thread.Sleep(2000); | 672 | Thread.Sleep(3000); |
668 | 673 | ||
669 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 674 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
670 | } | 675 | } |
@@ -804,7 +809,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
804 | 809 | ||
805 | #region Teleport Home | 810 | #region Teleport Home |
806 | 811 | ||
807 | public virtual void TeleportHome(UUID id, IClientAPI client) | 812 | public virtual void TriggerTeleportHome(UUID id, IClientAPI client) |
813 | { | ||
814 | TeleportHome(id, client); | ||
815 | } | ||
816 | |||
817 | public virtual bool TeleportHome(UUID id, IClientAPI client) | ||
808 | { | 818 | { |
809 | m_log.DebugFormat( | 819 | m_log.DebugFormat( |
810 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 820 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
@@ -814,12 +824,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
814 | 824 | ||
815 | if (uinfo != null) | 825 | if (uinfo != null) |
816 | { | 826 | { |
827 | if (uinfo.HomeRegionID == UUID.Zero) | ||
828 | { | ||
829 | // can't find the Home region: Tell viewer and abort | ||
830 | client.SendTeleportFailed("You don't have a home position set."); | ||
831 | return false; | ||
832 | } | ||
817 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 833 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
818 | if (regionInfo == null) | 834 | if (regionInfo == null) |
819 | { | 835 | { |
820 | // can't find the Home region: Tell viewer and abort | 836 | // can't find the Home region: Tell viewer and abort |
821 | client.SendTeleportFailed("Your home region could not be found."); | 837 | client.SendTeleportFailed("Your home region could not be found."); |
822 | return; | 838 | return false; |
823 | } | 839 | } |
824 | 840 | ||
825 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", | 841 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", |
@@ -832,10 +848,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
832 | } | 848 | } |
833 | else | 849 | else |
834 | { | 850 | { |
835 | m_log.ErrorFormat( | 851 | // can't find the Home region: Tell viewer and abort |
836 | "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", | 852 | client.SendTeleportFailed("Your home region could not be found."); |
837 | client.Name, client.AgentId); | 853 | return false; |
838 | } | 854 | } |
855 | return true; | ||
839 | } | 856 | } |
840 | 857 | ||
841 | #endregion | 858 | #endregion |
@@ -843,11 +860,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
843 | 860 | ||
844 | #region Agent Crossings | 861 | #region Agent Crossings |
845 | 862 | ||
846 | public bool Cross(ScenePresence agent, bool isFlying) | 863 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) |
847 | { | 864 | { |
848 | Scene scene = agent.Scene; | 865 | version = String.Empty; |
849 | Vector3 pos = agent.AbsolutePosition; | 866 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
850 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
851 | uint neighbourx = scene.RegionInfo.RegionLocX; | 867 | uint neighbourx = scene.RegionInfo.RegionLocX; |
852 | uint neighboury = scene.RegionInfo.RegionLocY; | 868 | uint neighboury = scene.RegionInfo.RegionLocY; |
853 | const float boundaryDistance = 1.7f; | 869 | const float boundaryDistance = 1.7f; |
@@ -868,52 +884,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
868 | } | 884 | } |
869 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 885 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
870 | { | 886 | { |
871 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 887 | neighboury--; |
872 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 888 | newpos.Y = Constants.RegionSize - enterDistance; |
873 | { | ||
874 | neighboury--; | ||
875 | newpos.Y = Constants.RegionSize - enterDistance; | ||
876 | } | ||
877 | else | ||
878 | { | ||
879 | agent.IsInTransit = true; | ||
880 | |||
881 | neighboury = b.TriggerRegionY; | ||
882 | neighbourx = b.TriggerRegionX; | ||
883 | |||
884 | Vector3 newposition = pos; | ||
885 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
886 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
887 | agent.ControllingClient.SendAgentAlertMessage( | ||
888 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
889 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
890 | return true; | ||
891 | } | ||
892 | } | ||
893 | |||
894 | Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); | ||
895 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
896 | { | ||
897 | neighbourx--; | ||
898 | newpos.X = Constants.RegionSize - enterDistance; | ||
899 | } | ||
900 | else | ||
901 | { | ||
902 | agent.IsInTransit = true; | ||
903 | |||
904 | neighboury = ba.TriggerRegionY; | ||
905 | neighbourx = ba.TriggerRegionX; | ||
906 | |||
907 | Vector3 newposition = pos; | ||
908 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
909 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
910 | agent.ControllingClient.SendAgentAlertMessage( | ||
911 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
912 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
913 | |||
914 | return true; | ||
915 | } | 889 | } |
916 | 890 | ||
891 | neighbourx--; | ||
892 | newpos.X = Constants.RegionSize - enterDistance; | ||
917 | } | 893 | } |
918 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | 894 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) |
919 | { | 895 | { |
@@ -923,26 +899,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
923 | 899 | ||
924 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 900 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
925 | { | 901 | { |
926 | Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 902 | neighboury--; |
927 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | 903 | newpos.Y = Constants.RegionSize - enterDistance; |
928 | { | ||
929 | neighboury--; | ||
930 | newpos.Y = Constants.RegionSize - enterDistance; | ||
931 | } | ||
932 | else | ||
933 | { | ||
934 | agent.IsInTransit = true; | ||
935 | |||
936 | neighboury = ba.TriggerRegionY; | ||
937 | neighbourx = ba.TriggerRegionX; | ||
938 | Vector3 newposition = pos; | ||
939 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
940 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
941 | agent.ControllingClient.SendAgentAlertMessage( | ||
942 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
943 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
944 | return true; | ||
945 | } | ||
946 | } | 904 | } |
947 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 905 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
948 | { | 906 | { |
@@ -954,25 +912,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
954 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 912 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
955 | { | 913 | { |
956 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 914 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); |
957 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 915 | neighboury--; |
958 | { | 916 | newpos.Y = Constants.RegionSize - enterDistance; |
959 | neighboury--; | ||
960 | newpos.Y = Constants.RegionSize - enterDistance; | ||
961 | } | ||
962 | else | ||
963 | { | ||
964 | agent.IsInTransit = true; | ||
965 | |||
966 | neighboury = b.TriggerRegionY; | ||
967 | neighbourx = b.TriggerRegionX; | ||
968 | Vector3 newposition = pos; | ||
969 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
970 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
971 | agent.ControllingClient.SendAgentAlertMessage( | ||
972 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
973 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
974 | return true; | ||
975 | } | ||
976 | } | 917 | } |
977 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 918 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
978 | { | 919 | { |
@@ -1006,19 +947,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1006 | } | 947 | } |
1007 | */ | 948 | */ |
1008 | 949 | ||
1009 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 950 | xDest = neighbourx; |
951 | yDest = neighboury; | ||
1010 | 952 | ||
1011 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); | 953 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); |
1012 | 954 | ||
955 | ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); | ||
956 | |||
1013 | ExpiringCache<ulong, DateTime> r; | 957 | ExpiringCache<ulong, DateTime> r; |
1014 | DateTime banUntil; | 958 | DateTime banUntil; |
1015 | 959 | ||
1016 | if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) | 960 | if (m_bannedRegions.TryGetValue(agentID, out r)) |
1017 | { | 961 | { |
1018 | if (r.TryGetValue(neighbourHandle, out banUntil)) | 962 | if (r.TryGetValue(neighbourHandle, out banUntil)) |
1019 | { | 963 | { |
1020 | if (DateTime.Now < banUntil) | 964 | if (DateTime.Now < banUntil) |
1021 | return false; | 965 | return null; |
1022 | r.Remove(neighbourHandle); | 966 | r.Remove(neighbourHandle); |
1023 | } | 967 | } |
1024 | } | 968 | } |
@@ -1030,28 +974,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1030 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 974 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1031 | 975 | ||
1032 | string reason; | 976 | string reason; |
1033 | string version; | 977 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
1034 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) | ||
1035 | { | 978 | { |
1036 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1037 | if (r == null) | 979 | if (r == null) |
1038 | { | 980 | { |
1039 | r = new ExpiringCache<ulong, DateTime>(); | 981 | r = new ExpiringCache<ulong, DateTime>(); |
1040 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 982 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1041 | 983 | ||
1042 | m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); | 984 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); |
1043 | } | 985 | } |
1044 | else | 986 | else |
1045 | { | 987 | { |
1046 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 988 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1047 | } | 989 | } |
990 | return null; | ||
991 | } | ||
992 | |||
993 | return neighbourRegion; | ||
994 | } | ||
995 | |||
996 | public bool Cross(ScenePresence agent, bool isFlying) | ||
997 | { | ||
998 | uint x; | ||
999 | uint y; | ||
1000 | Vector3 newpos; | ||
1001 | string version; | ||
1002 | |||
1003 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); | ||
1004 | if (neighbourRegion == null) | ||
1005 | { | ||
1006 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1048 | return false; | 1007 | return false; |
1049 | } | 1008 | } |
1050 | 1009 | ||
1051 | agent.IsInTransit = true; | 1010 | agent.IsInTransit = true; |
1052 | 1011 | ||
1053 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 1012 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; |
1054 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | 1013 | d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); |
1055 | 1014 | ||
1056 | return true; | 1015 | return true; |
1057 | } | 1016 | } |
@@ -1120,44 +1079,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1120 | icon.EndInvoke(iar); | 1079 | icon.EndInvoke(iar); |
1121 | } | 1080 | } |
1122 | 1081 | ||
1123 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | 1082 | public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) |
1083 | { | ||
1084 | if (neighbourRegion == null) | ||
1085 | return false; | ||
1086 | |||
1087 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1088 | |||
1089 | agent.RemoveFromPhysicalScene(); | ||
1090 | |||
1091 | return true; | ||
1092 | } | ||
1124 | 1093 | ||
1125 | /// <summary> | 1094 | /// <summary> |
1126 | /// This Closes child agents on neighbouring regions | 1095 | /// This Closes child agents on neighbouring regions |
1127 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1096 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1128 | /// </summary> | 1097 | /// </summary> |
1129 | protected ScenePresence CrossAgentToNewRegionAsync( | 1098 | public ScenePresence CrossAgentToNewRegionAsync( |
1130 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1099 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1131 | bool isFlying, string version) | 1100 | bool isFlying, string version) |
1132 | { | 1101 | { |
1133 | if (neighbourRegion == null) | 1102 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) |
1134 | return agent; | 1103 | return agent; |
1135 | 1104 | ||
1136 | try | 1105 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) |
1137 | { | 1106 | return agent; |
1138 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1139 | |||
1140 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | ||
1141 | |||
1142 | m_log.DebugFormat( | ||
1143 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1144 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
1145 | |||
1146 | Scene m_scene = agent.Scene; | ||
1147 | |||
1148 | if (!agent.ValidateAttachments()) | ||
1149 | m_log.DebugFormat( | ||
1150 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1151 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1152 | |||
1153 | pos = pos + agent.Velocity; | ||
1154 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1155 | 1107 | ||
1156 | agent.RemoveFromPhysicalScene(); | 1108 | CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); |
1109 | return agent; | ||
1110 | } | ||
1157 | 1111 | ||
1112 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) | ||
1113 | { | ||
1114 | try | ||
1115 | { | ||
1158 | AgentData cAgent = new AgentData(); | 1116 | AgentData cAgent = new AgentData(); |
1159 | agent.CopyTo(cAgent); | 1117 | agent.CopyTo(cAgent); |
1160 | cAgent.Position = pos; | 1118 | cAgent.Position = pos + agent.Velocity; |
1161 | if (isFlying) | 1119 | if (isFlying) |
1162 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 1120 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
1163 | 1121 | ||
@@ -1167,7 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1167 | // Beyond this point, extra cleanup is needed beyond removing transit state | 1125 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1168 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | 1126 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); |
1169 | 1127 | ||
1170 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1128 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) |
1171 | { | 1129 | { |
1172 | // region doesn't take it | 1130 | // region doesn't take it |
1173 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1131 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
@@ -1176,93 +1134,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1176 | agent.AddToPhysicalScene(isFlying); | 1134 | agent.AddToPhysicalScene(isFlying); |
1177 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1135 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1178 | 1136 | ||
1179 | return agent; | 1137 | return false; |
1180 | } | 1138 | } |
1181 | 1139 | ||
1182 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | 1140 | } |
1183 | agent.ControllingClient.RequestClientInfo(); | 1141 | catch (Exception e) |
1142 | { | ||
1143 | m_log.ErrorFormat( | ||
1144 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | ||
1145 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | ||
1184 | 1146 | ||
1185 | //m_log.Debug("BEFORE CROSS"); | 1147 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. |
1186 | //Scene.DumpChildrenSeeds(UUID); | 1148 | return false; |
1187 | //DumpKnownRegions(); | 1149 | } |
1188 | string agentcaps; | ||
1189 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1190 | { | ||
1191 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1192 | neighbourRegion.RegionHandle); | ||
1193 | return agent; | ||
1194 | } | ||
1195 | // No turning back | ||
1196 | agent.IsChildAgent = true; | ||
1197 | 1150 | ||
1198 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1151 | return true; |
1152 | } | ||
1199 | 1153 | ||
1200 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | 1154 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1155 | bool isFlying, string version) | ||
1156 | { | ||
1157 | agent.ControllingClient.RequestClientInfo(); | ||
1201 | 1158 | ||
1202 | if (m_eqModule != null) | 1159 | string agentcaps; |
1203 | { | 1160 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) |
1204 | m_eqModule.CrossRegion( | 1161 | { |
1205 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1162 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", |
1206 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | 1163 | neighbourRegion.RegionHandle); |
1207 | } | 1164 | return; |
1208 | else | 1165 | } |
1209 | { | ||
1210 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1211 | capsPath); | ||
1212 | } | ||
1213 | 1166 | ||
1214 | // SUCCESS! | 1167 | // No turning back |
1215 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | 1168 | agent.IsChildAgent = true; |
1216 | 1169 | ||
1217 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | 1170 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
1218 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | ||
1219 | 1171 | ||
1220 | agent.MakeChildAgent(); | 1172 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); |
1173 | |||
1174 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1175 | |||
1176 | if (m_eqModule != null) | ||
1177 | { | ||
1178 | m_eqModule.CrossRegion( | ||
1179 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | ||
1180 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1181 | } | ||
1182 | else | ||
1183 | { | ||
1184 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1185 | capsPath); | ||
1186 | } | ||
1221 | 1187 | ||
1222 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1188 | // SUCCESS! |
1223 | // but not sure yet what the side effects would be. | 1189 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
1224 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1225 | 1190 | ||
1226 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1191 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1227 | agent.SendOtherAgentsAvatarDataToMe(); | 1192 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1228 | agent.SendOtherAgentsAppearanceToMe(); | ||
1229 | 1193 | ||
1230 | // Backwards compatibility. Best effort | 1194 | agent.MakeChildAgent(); |
1231 | if (version == "Unknown" || version == string.Empty) | ||
1232 | { | ||
1233 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1234 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1235 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1236 | } | ||
1237 | 1195 | ||
1238 | // Next, let's close the child agent connections that are too far away. | 1196 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1239 | agent.CloseChildAgents(neighbourx, neighboury); | 1197 | // but not sure yet what the side effects would be. |
1198 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1240 | 1199 | ||
1241 | AgentHasMovedAway(agent, false); | 1200 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1201 | agent.SendOtherAgentsAvatarDataToMe(); | ||
1202 | agent.SendOtherAgentsAppearanceToMe(); | ||
1242 | 1203 | ||
1243 | // // the user may change their profile information in other region, | 1204 | // Backwards compatibility. Best effort |
1244 | // // so the userinfo in UserProfileCache is not reliable any more, delete it | 1205 | if (version == "Unknown" || version == string.Empty) |
1245 | // // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1246 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1247 | // { | ||
1248 | // m_log.DebugFormat( | ||
1249 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1250 | // } | ||
1251 | |||
1252 | //m_log.Debug("AFTER CROSS"); | ||
1253 | //Scene.DumpChildrenSeeds(UUID); | ||
1254 | //DumpKnownRegions(); | ||
1255 | } | ||
1256 | catch (Exception e) | ||
1257 | { | 1206 | { |
1258 | m_log.ErrorFormat( | 1207 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); |
1259 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | 1208 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback |
1260 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | 1209 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
1261 | |||
1262 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | ||
1263 | } | 1210 | } |
1264 | 1211 | ||
1265 | return agent; | 1212 | // Next, let's close the child agent connections that are too far away. |
1213 | uint neighbourx; | ||
1214 | uint neighboury; | ||
1215 | |||
1216 | Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1217 | |||
1218 | neighbourx /= Constants.RegionSize; | ||
1219 | neighboury /= Constants.RegionSize; | ||
1220 | |||
1221 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1222 | |||
1223 | AgentHasMovedAway(agent, false); | ||
1224 | |||
1225 | // the user may change their profile information in other region, | ||
1226 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1227 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1228 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1229 | // { | ||
1230 | // m_log.DebugFormat( | ||
1231 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1232 | // } | ||
1233 | |||
1234 | //m_log.Debug("AFTER CROSS"); | ||
1235 | //Scene.DumpChildrenSeeds(UUID); | ||
1236 | //DumpKnownRegions(); | ||
1237 | |||
1238 | return; | ||
1266 | } | 1239 | } |
1267 | 1240 | ||
1268 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1241 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
@@ -1333,10 +1306,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1333 | agent.Id0 = currentAgentCircuit.Id0; | 1306 | agent.Id0 = currentAgentCircuit.Id0; |
1334 | } | 1307 | } |
1335 | 1308 | ||
1336 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 1309 | IPEndPoint external = region.ExternalEndPoint; |
1337 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | 1310 | if (external != null) |
1311 | { | ||
1312 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
1313 | d.BeginInvoke(sp, agent, region, external, true, | ||
1338 | InformClientOfNeighbourCompleted, | 1314 | InformClientOfNeighbourCompleted, |
1339 | d); | 1315 | d); |
1316 | } | ||
1340 | } | 1317 | } |
1341 | #endregion | 1318 | #endregion |
1342 | 1319 | ||
@@ -1917,27 +1894,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1917 | Utils.LongToUInts(newRegionHandle, out x, out y); | 1894 | Utils.LongToUInts(newRegionHandle, out x, out y); |
1918 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 1895 | GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
1919 | 1896 | ||
1920 | if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) | 1897 | if (destination != null) |
1921 | { | 1898 | { |
1922 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); | 1899 | if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) |
1900 | return; // we did it | ||
1901 | } | ||
1923 | 1902 | ||
1924 | // We are going to move the object back to the old position so long as the old position | 1903 | // no one or failed lets go back and tell physics to go on |
1925 | // is in the region | 1904 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f); |
1926 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); | 1905 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f); |
1927 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); | 1906 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f); |
1928 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); | ||
1929 | 1907 | ||
1930 | grp.RootPart.GroupPosition = oldGroupPosition; | 1908 | grp.AbsolutePosition = oldGroupPosition; |
1909 | grp.Velocity = Vector3.Zero; | ||
1931 | 1910 | ||
1932 | // Need to turn off the physics flags, otherwise the object will continue to attempt to | 1911 | if (grp.RootPart.PhysActor != null) |
1933 | // move out of the region creating an infinite loop of failed attempts to cross | 1912 | grp.RootPart.PhysActor.CrossingFailure(); |
1934 | grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); | ||
1935 | 1913 | ||
1936 | grp.ScheduleGroupForFullUpdate(); | 1914 | if (grp.RootPart.KeyframeMotion != null) |
1937 | } | 1915 | grp.RootPart.KeyframeMotion.CrossingFailure(); |
1916 | |||
1917 | grp.ScheduleGroupForFullUpdate(); | ||
1938 | } | 1918 | } |
1939 | 1919 | ||
1940 | 1920 | ||
1921 | |||
1941 | /// <summary> | 1922 | /// <summary> |
1942 | /// Move the given scene object into a new region | 1923 | /// Move the given scene object into a new region |
1943 | /// </summary> | 1924 | /// </summary> |
@@ -1988,17 +1969,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1988 | grp, e); | 1969 | grp, e); |
1989 | } | 1970 | } |
1990 | } | 1971 | } |
1972 | /* | ||
1973 | * done on caller ( not in attachments crossing for now) | ||
1991 | else | 1974 | else |
1992 | { | 1975 | { |
1976 | |||
1993 | if (!grp.IsDeleted) | 1977 | if (!grp.IsDeleted) |
1994 | { | 1978 | { |
1995 | PhysicsActor pa = grp.RootPart.PhysActor; | 1979 | PhysicsActor pa = grp.RootPart.PhysActor; |
1996 | if (pa != null) | 1980 | if (pa != null) |
1981 | { | ||
1997 | pa.CrossingFailure(); | 1982 | pa.CrossingFailure(); |
1983 | if (grp.RootPart.KeyframeMotion != null) | ||
1984 | { | ||
1985 | // moved to KeyframeMotion.CrossingFailure | ||
1986 | // grp.RootPart.Velocity = Vector3.Zero; | ||
1987 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
1988 | // grp.SendGroupRootTerseUpdate(); | ||
1989 | } | ||
1990 | } | ||
1998 | } | 1991 | } |
1999 | 1992 | ||
2000 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | 1993 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); |
2001 | } | 1994 | } |
1995 | */ | ||
2002 | } | 1996 | } |
2003 | else | 1997 | else |
2004 | { | 1998 | { |
@@ -2083,4 +2077,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2083 | #endregion | 2077 | #endregion |
2084 | 2078 | ||
2085 | } | 2079 | } |
2086 | } \ No newline at end of file | 2080 | } |