aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs433
1 files changed, 209 insertions, 224 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ca0cef1..6e19805 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
243 243
244 protected virtual void OnNewClient(IClientAPI client) 244 protected virtual void OnNewClient(IClientAPI client)
245 { 245 {
246 client.OnTeleportHomeRequest += TeleportHome; 246 client.OnTeleportHomeRequest += TriggerTeleportHome;
247 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 247 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
248 248
249 if (!DisableInterRegionTeleportCancellation) 249 if (!DisableInterRegionTeleportCancellation)
@@ -367,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
367 /// <param name="sp"></param> 367 /// <param name="sp"></param>
368 /// <param name="position"></param> 368 /// <param name="position"></param>
369 /// <param name="lookAt"></param> 369 /// <param name="lookAt"></param>
370 /// <param name="teleportFlags"></param 370 /// <param name="teleportFlags"></param>
371 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 371 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
372 { 372 {
373 m_log.DebugFormat( 373 m_log.DebugFormat(
@@ -402,11 +402,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
402 position.Z = newPosZ; 402 position.Z = newPosZ;
403 } 403 }
404 404
405 if (sp.Flying)
406 teleportFlags |= (uint)TeleportFlags.IsFlying;
407
405 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 408 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
406 409
407 sp.ControllingClient.SendTeleportStart(teleportFlags); 410 sp.ControllingClient.SendTeleportStart(teleportFlags);
408 411
409 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 412 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
413 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
410 sp.Velocity = Vector3.Zero; 414 sp.Velocity = Vector3.Zero;
411 sp.Teleport(position); 415 sp.Teleport(position);
412 416
@@ -607,8 +611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
607 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 611 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
608 // it's actually doing a lot of work. 612 // it's actually doing a lot of work.
609 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 613 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
610 614 if (endPoint == null || endPoint.Address == null)
611 if (endPoint.Address == null)
612 { 615 {
613 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 616 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
614 617
@@ -645,6 +648,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
645 // both regions 648 // both regions
646 if (sp.ParentID != (uint)0) 649 if (sp.ParentID != (uint)0)
647 sp.StandUp(); 650 sp.StandUp();
651 else if (sp.Flying)
652 teleportFlags |= (uint)TeleportFlags.IsFlying;
648 653
649 if (DisableInterRegionTeleportCancellation) 654 if (DisableInterRegionTeleportCancellation)
650 teleportFlags |= (uint)TeleportFlags.DisableCancel; 655 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -907,7 +912,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
907 // 912 //
908 // This sleep can be increased if necessary. However, whilst it's active, 913 // This sleep can be increased if necessary. However, whilst it's active,
909 // an agent cannot teleport back to this region if it has teleported away. 914 // an agent cannot teleport back to this region if it has teleported away.
910 Thread.Sleep(2000); 915 Thread.Sleep(3000);
911 916
912 sp.Scene.IncomingCloseAgent(sp.UUID, false); 917 sp.Scene.IncomingCloseAgent(sp.UUID, false);
913 } 918 }
@@ -1071,7 +1076,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1071 1076
1072 #region Teleport Home 1077 #region Teleport Home
1073 1078
1074 public virtual void TeleportHome(UUID id, IClientAPI client) 1079 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1080 {
1081 TeleportHome(id, client);
1082 }
1083
1084 public virtual bool TeleportHome(UUID id, IClientAPI client)
1075 { 1085 {
1076 m_log.DebugFormat( 1086 m_log.DebugFormat(
1077 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 1087 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -1081,12 +1091,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1081 1091
1082 if (uinfo != null) 1092 if (uinfo != null)
1083 { 1093 {
1094 if (uinfo.HomeRegionID == UUID.Zero)
1095 {
1096 // can't find the Home region: Tell viewer and abort
1097 client.SendTeleportFailed("You don't have a home position set.");
1098 return false;
1099 }
1084 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1100 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1085 if (regionInfo == null) 1101 if (regionInfo == null)
1086 { 1102 {
1087 // can't find the Home region: Tell viewer and abort 1103 // can't find the Home region: Tell viewer and abort
1088 client.SendTeleportFailed("Your home region could not be found."); 1104 client.SendTeleportFailed("Your home region could not be found.");
1089 return; 1105 return false;
1090 } 1106 }
1091 1107
1092 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 1108 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
@@ -1099,10 +1115,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1099 } 1115 }
1100 else 1116 else
1101 { 1117 {
1102 m_log.ErrorFormat( 1118 // can't find the Home region: Tell viewer and abort
1103 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1119 client.SendTeleportFailed("Your home region could not be found.");
1104 client.Name, client.AgentId); 1120 return false;
1105 } 1121 }
1122 return true;
1106 } 1123 }
1107 1124
1108 #endregion 1125 #endregion
@@ -1110,15 +1127,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1110 1127
1111 #region Agent Crossings 1128 #region Agent Crossings
1112 1129
1113 public bool Cross(ScenePresence agent, bool isFlying) 1130 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1114 { 1131 {
1115 Scene scene = agent.Scene; 1132 version = String.Empty;
1116 Vector3 pos = agent.AbsolutePosition; 1133 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1117 1134
1118// m_log.DebugFormat( 1135// m_log.DebugFormat(
1119// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1136// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1120 1137
1121 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1122 uint neighbourx = scene.RegionInfo.RegionLocX; 1138 uint neighbourx = scene.RegionInfo.RegionLocX;
1123 uint neighboury = scene.RegionInfo.RegionLocY; 1139 uint neighboury = scene.RegionInfo.RegionLocY;
1124 const float boundaryDistance = 1.7f; 1140 const float boundaryDistance = 1.7f;
@@ -1139,52 +1155,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1139 } 1155 }
1140 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1156 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1141 { 1157 {
1142 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1158 neighboury--;
1143 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1159 newpos.Y = Constants.RegionSize - enterDistance;
1144 {
1145 neighboury--;
1146 newpos.Y = Constants.RegionSize - enterDistance;
1147 }
1148 else
1149 {
1150 agent.IsInTransit = true;
1151
1152 neighboury = b.TriggerRegionY;
1153 neighbourx = b.TriggerRegionX;
1154
1155 Vector3 newposition = pos;
1156 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1157 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1158 agent.ControllingClient.SendAgentAlertMessage(
1159 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1160 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1161 return true;
1162 }
1163 }
1164
1165 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1166 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1167 {
1168 neighbourx--;
1169 newpos.X = Constants.RegionSize - enterDistance;
1170 }
1171 else
1172 {
1173 agent.IsInTransit = true;
1174
1175 neighboury = ba.TriggerRegionY;
1176 neighbourx = ba.TriggerRegionX;
1177
1178 Vector3 newposition = pos;
1179 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1180 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1181 agent.ControllingClient.SendAgentAlertMessage(
1182 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1183 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1184
1185 return true;
1186 } 1160 }
1187 1161
1162 neighbourx--;
1163 newpos.X = Constants.RegionSize - enterDistance;
1188 } 1164 }
1189 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1165 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1190 { 1166 {
@@ -1194,26 +1170,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1194 1170
1195 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1171 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1196 { 1172 {
1197 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1173 neighboury--;
1198 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1174 newpos.Y = Constants.RegionSize - enterDistance;
1199 {
1200 neighboury--;
1201 newpos.Y = Constants.RegionSize - enterDistance;
1202 }
1203 else
1204 {
1205 agent.IsInTransit = true;
1206
1207 neighboury = ba.TriggerRegionY;
1208 neighbourx = ba.TriggerRegionX;
1209 Vector3 newposition = pos;
1210 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1211 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1212 agent.ControllingClient.SendAgentAlertMessage(
1213 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1214 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1215 return true;
1216 }
1217 } 1175 }
1218 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1176 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1219 { 1177 {
@@ -1225,25 +1183,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1225 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1183 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1226 { 1184 {
1227 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1185 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1228 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1186 neighboury--;
1229 { 1187 newpos.Y = Constants.RegionSize - enterDistance;
1230 neighboury--;
1231 newpos.Y = Constants.RegionSize - enterDistance;
1232 }
1233 else
1234 {
1235 agent.IsInTransit = true;
1236
1237 neighboury = b.TriggerRegionY;
1238 neighbourx = b.TriggerRegionX;
1239 Vector3 newposition = pos;
1240 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1241 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1242 agent.ControllingClient.SendAgentAlertMessage(
1243 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1244 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1245 return true;
1246 }
1247 } 1188 }
1248 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1189 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1249 { 1190 {
@@ -1277,19 +1218,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1277 } 1218 }
1278 */ 1219 */
1279 1220
1280 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1221 xDest = neighbourx;
1222 yDest = neighboury;
1281 1223
1282 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1224 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1283 1225
1226 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1227
1284 ExpiringCache<ulong, DateTime> r; 1228 ExpiringCache<ulong, DateTime> r;
1285 DateTime banUntil; 1229 DateTime banUntil;
1286 1230
1287 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1231 if (m_bannedRegions.TryGetValue(agentID, out r))
1288 { 1232 {
1289 if (r.TryGetValue(neighbourHandle, out banUntil)) 1233 if (r.TryGetValue(neighbourHandle, out banUntil))
1290 { 1234 {
1291 if (DateTime.Now < banUntil) 1235 if (DateTime.Now < banUntil)
1292 return false; 1236 return null;
1293 r.Remove(neighbourHandle); 1237 r.Remove(neighbourHandle);
1294 } 1238 }
1295 } 1239 }
@@ -1301,28 +1245,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1301 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1245 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1302 1246
1303 string reason; 1247 string reason;
1304 string version; 1248 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1305 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1306 { 1249 {
1307 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1308 if (r == null) 1250 if (r == null)
1309 { 1251 {
1310 r = new ExpiringCache<ulong, DateTime>(); 1252 r = new ExpiringCache<ulong, DateTime>();
1311 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1253 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1312 1254
1313 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1255 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1314 } 1256 }
1315 else 1257 else
1316 { 1258 {
1317 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1259 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1318 } 1260 }
1261 return null;
1262 }
1263
1264 return neighbourRegion;
1265 }
1266
1267 public bool Cross(ScenePresence agent, bool isFlying)
1268 {
1269 uint x;
1270 uint y;
1271 Vector3 newpos;
1272 string version;
1273
1274 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1275 if (neighbourRegion == null)
1276 {
1277 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1319 return false; 1278 return false;
1320 } 1279 }
1321 1280
1322 agent.IsInTransit = true; 1281 agent.IsInTransit = true;
1323 1282
1324 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1283 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1325 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1284 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1326 1285
1327 return true; 1286 return true;
1328 } 1287 }
@@ -1404,52 +1363,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1404 icon.EndInvoke(iar); 1363 icon.EndInvoke(iar);
1405 } 1364 }
1406 1365
1407 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1366 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1367 {
1368 if (neighbourRegion == null)
1369 return false;
1370
1371 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1372
1373 agent.RemoveFromPhysicalScene();
1374
1375 return true;
1376 }
1408 1377
1409 /// <summary> 1378 /// <summary>
1410 /// This Closes child agents on neighbouring regions 1379 /// This Closes child agents on neighbouring regions
1411 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1380 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1412 /// </summary> 1381 /// </summary>
1413 protected ScenePresence CrossAgentToNewRegionAsync( 1382 public ScenePresence CrossAgentToNewRegionAsync(
1414 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1383 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1415 bool isFlying, string version) 1384 bool isFlying, string version)
1416 { 1385 {
1417 if (neighbourRegion == null) 1386 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1387 {
1388 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1418 return agent; 1389 return agent;
1390 }
1419 1391
1420 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1392 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1421 { 1393 {
1422 m_log.ErrorFormat( 1394 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1423 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1424 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1425 return agent; 1395 return agent;
1426 } 1396 }
1427 1397
1428 bool transitWasReset = false; 1398 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1399 return agent;
1400 }
1429 1401
1402 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1403 {
1430 try 1404 try
1431 { 1405 {
1432 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1406 AgentData cAgent = new AgentData();
1433
1434 m_log.DebugFormat(
1435 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1436 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1437
1438 Scene m_scene = agent.Scene;
1439
1440 if (!agent.ValidateAttachments())
1441 m_log.DebugFormat(
1442 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1443 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1444
1445 pos = pos + agent.Velocity;
1446 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1447
1448 agent.RemoveFromPhysicalScene();
1449
1450 AgentData cAgent = new AgentData();
1451 agent.CopyTo(cAgent); 1407 agent.CopyTo(cAgent);
1452 cAgent.Position = pos; 1408 cAgent.Position = pos + agent.Velocity;
1453 if (isFlying) 1409 if (isFlying)
1454 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1410 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1455 1411
@@ -1459,7 +1415,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1459 // Beyond this point, extra cleanup is needed beyond removing transit state 1415 // Beyond this point, extra cleanup is needed beyond removing transit state
1460 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1416 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1461 1417
1462 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1418 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1463 { 1419 {
1464 // region doesn't take it 1420 // region doesn't take it
1465 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1421 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1471,100 +1427,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1471 ReInstantiateScripts(agent); 1427 ReInstantiateScripts(agent);
1472 agent.AddToPhysicalScene(isFlying); 1428 agent.AddToPhysicalScene(isFlying);
1473 1429
1474 return agent; 1430 return false;
1475 } 1431 }
1476 1432
1477 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1433 }
1478 agent.ControllingClient.RequestClientInfo(); 1434 catch (Exception e)
1435 {
1436 m_log.ErrorFormat(
1437 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1438 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1479 1439
1480 //m_log.Debug("BEFORE CROSS"); 1440 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1481 //Scene.DumpChildrenSeeds(UUID); 1441 return false;
1482 //DumpKnownRegions(); 1442 }
1483 string agentcaps;
1484 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1485 {
1486 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1487 neighbourRegion.RegionHandle);
1488 return agent;
1489 }
1490 1443
1491 // No turning back 1444 return true;
1492 agent.IsChildAgent = true; 1445 }
1493 1446
1494 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1447 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1448 bool isFlying, string version)
1449 {
1450 agent.ControllingClient.RequestClientInfo();
1495 1451
1496 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1452 string agentcaps;
1453 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1454 {
1455 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1456 neighbourRegion.RegionHandle);
1457 return;
1458 }
1497 1459
1498 if (m_eqModule != null) 1460 // No turning back
1499 { 1461 agent.IsChildAgent = true;
1500 m_eqModule.CrossRegion(
1501 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1502 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1503 }
1504 else
1505 {
1506 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1507 capsPath);
1508 }
1509 1462
1510 // SUCCESS! 1463 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1511 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1512 1464
1513 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1465 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1514 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1515 1466
1516 agent.MakeChildAgent(); 1467 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1517 1468
1518 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1469 if (m_eqModule != null)
1519 // but not sure yet what the side effects would be. 1470 {
1520 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1471 m_eqModule.CrossRegion(
1521 transitWasReset = true; 1472 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1473 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1474 }
1475 else
1476 {
1477 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1478 capsPath);
1479 }
1522 1480
1523 // now we have a child agent in this region. Request all interesting data about other (root) agents 1481 // SUCCESS!
1524 agent.SendOtherAgentsAvatarDataToMe(); 1482 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1525 agent.SendOtherAgentsAppearanceToMe();
1526 1483
1527 // Backwards compatibility. Best effort 1484 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1528 if (version == "Unknown" || version == string.Empty) 1485 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1529 {
1530 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1531 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1532 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1533 }
1534 1486
1535 // Next, let's close the child agent connections that are too far away. 1487 agent.MakeChildAgent();
1536 agent.CloseChildAgents(neighbourx, neighboury);
1537 1488
1538 AgentHasMovedAway(agent, false); 1489 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1490 // but not sure yet what the side effects would be.
1491 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1539 1492
1540// // the user may change their profile information in other region, 1493 // now we have a child agent in this region. Request all interesting data about other (root) agents
1541// // so the userinfo in UserProfileCache is not reliable any more, delete it 1494 agent.SendOtherAgentsAvatarDataToMe();
1542// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1495 agent.SendOtherAgentsAppearanceToMe();
1543// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1544// {
1545// m_log.DebugFormat(
1546// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1547// }
1548
1549 //m_log.Debug("AFTER CROSS");
1550 //Scene.DumpChildrenSeeds(UUID);
1551 //DumpKnownRegions();
1552 }
1553 catch (Exception e)
1554 {
1555 m_log.ErrorFormat(
1556 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1557 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1558 1496
1559 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1497 // Backwards compatibility. Best effort
1560 } 1498 if (version == "Unknown" || version == string.Empty)
1561 finally
1562 { 1499 {
1563 if (!transitWasReset) 1500 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1564 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1501 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1502 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1565 } 1503 }
1566 1504
1567 return agent; 1505 // Next, let's close the child agent connections that are too far away.
1506 uint neighbourx;
1507 uint neighboury;
1508
1509 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1510
1511 neighbourx /= Constants.RegionSize;
1512 neighboury /= Constants.RegionSize;
1513
1514 agent.CloseChildAgents(neighbourx, neighboury);
1515
1516 AgentHasMovedAway(agent, false);
1517
1518 // the user may change their profile information in other region,
1519 // so the userinfo in UserProfileCache is not reliable any more, delete it
1520 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1521// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1522// {
1523// m_log.DebugFormat(
1524// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1525// }
1526
1527 //m_log.Debug("AFTER CROSS");
1528 //Scene.DumpChildrenSeeds(UUID);
1529 //DumpKnownRegions();
1530
1531 return;
1568 } 1532 }
1569 1533
1570 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1534 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1635,10 +1599,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1635 agent.Id0 = currentAgentCircuit.Id0; 1599 agent.Id0 = currentAgentCircuit.Id0;
1636 } 1600 }
1637 1601
1638 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1602 IPEndPoint external = region.ExternalEndPoint;
1639 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1603 if (external != null)
1604 {
1605 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1606 d.BeginInvoke(sp, agent, region, external, true,
1640 InformClientOfNeighbourCompleted, 1607 InformClientOfNeighbourCompleted,
1641 d); 1608 d);
1609 }
1642 } 1610 }
1643 #endregion 1611 #endregion
1644 1612
@@ -2235,27 +2203,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2235 Utils.LongToUInts(newRegionHandle, out x, out y); 2203 Utils.LongToUInts(newRegionHandle, out x, out y);
2236 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2204 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2237 2205
2238 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2206 if (destination != null)
2239 { 2207 {
2240 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2208 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2209 return; // we did it
2210 }
2241 2211
2242 // We are going to move the object back to the old position so long as the old position 2212 // no one or failed lets go back and tell physics to go on
2243 // is in the region 2213 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2244 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2214 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2245 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2215 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2246 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2247 2216
2248 grp.RootPart.GroupPosition = oldGroupPosition; 2217 grp.AbsolutePosition = oldGroupPosition;
2218 grp.Velocity = Vector3.Zero;
2249 2219
2250 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2220 if (grp.RootPart.PhysActor != null)
2251 // move out of the region creating an infinite loop of failed attempts to cross 2221 grp.RootPart.PhysActor.CrossingFailure();
2252 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2253 2222
2254 grp.ScheduleGroupForFullUpdate(); 2223 if (grp.RootPart.KeyframeMotion != null)
2255 } 2224 grp.RootPart.KeyframeMotion.CrossingFailure();
2225
2226 grp.ScheduleGroupForFullUpdate();
2256 } 2227 }
2257 2228
2258 2229
2230
2259 /// <summary> 2231 /// <summary>
2260 /// Move the given scene object into a new region 2232 /// Move the given scene object into a new region
2261 /// </summary> 2233 /// </summary>
@@ -2306,17 +2278,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2306 grp, e); 2278 grp, e);
2307 } 2279 }
2308 } 2280 }
2281/*
2282 * done on caller ( not in attachments crossing for now)
2309 else 2283 else
2310 { 2284 {
2285
2311 if (!grp.IsDeleted) 2286 if (!grp.IsDeleted)
2312 { 2287 {
2313 PhysicsActor pa = grp.RootPart.PhysActor; 2288 PhysicsActor pa = grp.RootPart.PhysActor;
2314 if (pa != null) 2289 if (pa != null)
2290 {
2315 pa.CrossingFailure(); 2291 pa.CrossingFailure();
2292 if (grp.RootPart.KeyframeMotion != null)
2293 {
2294 // moved to KeyframeMotion.CrossingFailure
2295// grp.RootPart.Velocity = Vector3.Zero;
2296 grp.RootPart.KeyframeMotion.CrossingFailure();
2297// grp.SendGroupRootTerseUpdate();
2298 }
2299 }
2316 } 2300 }
2317 2301
2318 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2302 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2319 } 2303 }
2304 */
2320 } 2305 }
2321 else 2306 else
2322 { 2307 {