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.cs421
1 files changed, 204 insertions, 217 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 4219254..ed14c12 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
369 /// <param name="sp"></param> 369 /// <param name="sp"></param>
370 /// <param name="position"></param> 370 /// <param name="position"></param>
371 /// <param name="lookAt"></param> 371 /// <param name="lookAt"></param>
372 /// <param name="teleportFlags"></param 372 /// <param name="teleportFlags"></param>
373 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 373 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
374 { 374 {
375 m_log.DebugFormat( 375 m_log.DebugFormat(
@@ -404,11 +404,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
404 position.Z = newPosZ; 404 position.Z = newPosZ;
405 } 405 }
406 406
407 if (sp.Flying)
408 teleportFlags |= (uint)TeleportFlags.IsFlying;
409
407 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 410 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
408 411
409 sp.ControllingClient.SendTeleportStart(teleportFlags); 412 sp.ControllingClient.SendTeleportStart(teleportFlags);
410 413
411 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 414 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
415 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
412 sp.Velocity = Vector3.Zero; 416 sp.Velocity = Vector3.Zero;
413 sp.Teleport(position); 417 sp.Teleport(position);
414 418
@@ -609,8 +613,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
609 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 613 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
610 // it's actually doing a lot of work. 614 // it's actually doing a lot of work.
611 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 615 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
612 616 if (endPoint == null || endPoint.Address == null)
613 if (endPoint.Address == null)
614 { 617 {
615 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 618 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
616 619
@@ -647,6 +650,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
647 // both regions 650 // both regions
648 if (sp.ParentID != (uint)0) 651 if (sp.ParentID != (uint)0)
649 sp.StandUp(); 652 sp.StandUp();
653 else if (sp.Flying)
654 teleportFlags |= (uint)TeleportFlags.IsFlying;
650 655
651 if (DisableInterRegionTeleportCancellation) 656 if (DisableInterRegionTeleportCancellation)
652 teleportFlags |= (uint)TeleportFlags.DisableCancel; 657 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -1267,11 +1272,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1267 1272
1268 #region Teleport Home 1273 #region Teleport Home
1269 1274
1270 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1275 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1271 { 1276 {
1272 TeleportHome(id, client); 1277 TeleportHome(id, client);
1273 } 1278 }
1274 1279
1275 public virtual bool TeleportHome(UUID id, IClientAPI client) 1280 public virtual bool TeleportHome(UUID id, IClientAPI client)
1276 { 1281 {
1277 m_log.DebugFormat( 1282 m_log.DebugFormat(
@@ -1282,6 +1287,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1282 1287
1283 if (uinfo != null) 1288 if (uinfo != null)
1284 { 1289 {
1290 if (uinfo.HomeRegionID == UUID.Zero)
1291 {
1292 // can't find the Home region: Tell viewer and abort
1293 client.SendTeleportFailed("You don't have a home position set.");
1294 return false;
1295 }
1285 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1296 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1286 if (regionInfo == null) 1297 if (regionInfo == null)
1287 { 1298 {
@@ -1301,9 +1312,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1301 } 1312 }
1302 else 1313 else
1303 { 1314 {
1304 m_log.ErrorFormat( 1315 // can't find the Home region: Tell viewer and abort
1305 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1316 client.SendTeleportFailed("Your home region could not be found.");
1306 client.Name, client.AgentId);
1307 } 1317 }
1308 return false; 1318 return false;
1309 } 1319 }
@@ -1313,15 +1323,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1313 1323
1314 #region Agent Crossings 1324 #region Agent Crossings
1315 1325
1316 public bool Cross(ScenePresence agent, bool isFlying) 1326 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1317 { 1327 {
1318 Scene scene = agent.Scene; 1328 version = String.Empty;
1319 Vector3 pos = agent.AbsolutePosition; 1329 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1320 1330
1321// m_log.DebugFormat( 1331// m_log.DebugFormat(
1322// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1332// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1323 1333
1324 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1325 uint neighbourx = scene.RegionInfo.RegionLocX; 1334 uint neighbourx = scene.RegionInfo.RegionLocX;
1326 uint neighboury = scene.RegionInfo.RegionLocY; 1335 uint neighboury = scene.RegionInfo.RegionLocY;
1327 const float boundaryDistance = 1.7f; 1336 const float boundaryDistance = 1.7f;
@@ -1342,52 +1351,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1342 } 1351 }
1343 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1352 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1344 { 1353 {
1345 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1354 neighboury--;
1346 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1355 newpos.Y = Constants.RegionSize - enterDistance;
1347 {
1348 neighboury--;
1349 newpos.Y = Constants.RegionSize - enterDistance;
1350 }
1351 else
1352 {
1353 agent.IsInTransit = true;
1354
1355 neighboury = b.TriggerRegionY;
1356 neighbourx = b.TriggerRegionX;
1357
1358 Vector3 newposition = pos;
1359 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1360 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1361 agent.ControllingClient.SendAgentAlertMessage(
1362 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1363 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1364 return true;
1365 }
1366 }
1367
1368 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1369 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1370 {
1371 neighbourx--;
1372 newpos.X = Constants.RegionSize - enterDistance;
1373 }
1374 else
1375 {
1376 agent.IsInTransit = true;
1377
1378 neighboury = ba.TriggerRegionY;
1379 neighbourx = ba.TriggerRegionX;
1380
1381 Vector3 newposition = pos;
1382 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1383 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1384 agent.ControllingClient.SendAgentAlertMessage(
1385 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1386 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1387
1388 return true;
1389 } 1356 }
1390 1357
1358 neighbourx--;
1359 newpos.X = Constants.RegionSize - enterDistance;
1391 } 1360 }
1392 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1361 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1393 { 1362 {
@@ -1397,26 +1366,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1397 1366
1398 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1367 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1399 { 1368 {
1400 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1369 neighboury--;
1401 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1370 newpos.Y = Constants.RegionSize - enterDistance;
1402 {
1403 neighboury--;
1404 newpos.Y = Constants.RegionSize - enterDistance;
1405 }
1406 else
1407 {
1408 agent.IsInTransit = true;
1409
1410 neighboury = ba.TriggerRegionY;
1411 neighbourx = ba.TriggerRegionX;
1412 Vector3 newposition = pos;
1413 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1414 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1415 agent.ControllingClient.SendAgentAlertMessage(
1416 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1417 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1418 return true;
1419 }
1420 } 1371 }
1421 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1372 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1422 { 1373 {
@@ -1428,25 +1379,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1428 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1379 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1429 { 1380 {
1430 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1381 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1431 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1382 neighboury--;
1432 { 1383 newpos.Y = Constants.RegionSize - enterDistance;
1433 neighboury--;
1434 newpos.Y = Constants.RegionSize - enterDistance;
1435 }
1436 else
1437 {
1438 agent.IsInTransit = true;
1439
1440 neighboury = b.TriggerRegionY;
1441 neighbourx = b.TriggerRegionX;
1442 Vector3 newposition = pos;
1443 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1444 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1445 agent.ControllingClient.SendAgentAlertMessage(
1446 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1447 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1448 return true;
1449 }
1450 } 1384 }
1451 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1385 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1452 { 1386 {
@@ -1480,19 +1414,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1480 } 1414 }
1481 */ 1415 */
1482 1416
1483 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1417 xDest = neighbourx;
1418 yDest = neighboury;
1484 1419
1485 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1420 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1486 1421
1422 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1423
1487 ExpiringCache<ulong, DateTime> r; 1424 ExpiringCache<ulong, DateTime> r;
1488 DateTime banUntil; 1425 DateTime banUntil;
1489 1426
1490 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1427 if (m_bannedRegions.TryGetValue(agentID, out r))
1491 { 1428 {
1492 if (r.TryGetValue(neighbourHandle, out banUntil)) 1429 if (r.TryGetValue(neighbourHandle, out banUntil))
1493 { 1430 {
1494 if (DateTime.Now < banUntil) 1431 if (DateTime.Now < banUntil)
1495 return false; 1432 return null;
1496 r.Remove(neighbourHandle); 1433 r.Remove(neighbourHandle);
1497 } 1434 }
1498 } 1435 }
@@ -1504,28 +1441,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1504 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1441 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1505 1442
1506 string reason; 1443 string reason;
1507 string version; 1444 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1508 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1509 { 1445 {
1510 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1511 if (r == null) 1446 if (r == null)
1512 { 1447 {
1513 r = new ExpiringCache<ulong, DateTime>(); 1448 r = new ExpiringCache<ulong, DateTime>();
1514 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1449 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1515 1450
1516 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1451 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1517 } 1452 }
1518 else 1453 else
1519 { 1454 {
1520 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1455 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1521 } 1456 }
1457 return null;
1458 }
1459
1460 return neighbourRegion;
1461 }
1462
1463 public bool Cross(ScenePresence agent, bool isFlying)
1464 {
1465 uint x;
1466 uint y;
1467 Vector3 newpos;
1468 string version;
1469
1470 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1471 if (neighbourRegion == null)
1472 {
1473 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1522 return false; 1474 return false;
1523 } 1475 }
1524 1476
1525 agent.IsInTransit = true; 1477 agent.IsInTransit = true;
1526 1478
1527 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1479 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1528 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1480 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1529 1481
1530 return true; 1482 return true;
1531 } 1483 }
@@ -1607,52 +1559,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1607 icon.EndInvoke(iar); 1559 icon.EndInvoke(iar);
1608 } 1560 }
1609 1561
1610 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1562 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1563 {
1564 if (neighbourRegion == null)
1565 return false;
1566
1567 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1568
1569 agent.RemoveFromPhysicalScene();
1570
1571 return true;
1572 }
1611 1573
1612 /// <summary> 1574 /// <summary>
1613 /// This Closes child agents on neighbouring regions 1575 /// This Closes child agents on neighbouring regions
1614 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1576 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1615 /// </summary> 1577 /// </summary>
1616 protected ScenePresence CrossAgentToNewRegionAsync( 1578 public ScenePresence CrossAgentToNewRegionAsync(
1617 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1579 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1618 bool isFlying, string version) 1580 bool isFlying, string version)
1619 { 1581 {
1620 if (neighbourRegion == null) 1582 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1583 {
1584 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1621 return agent; 1585 return agent;
1586 }
1622 1587
1623 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1588 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1624 { 1589 {
1625 m_log.ErrorFormat( 1590 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1626 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1627 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1628 return agent; 1591 return agent;
1629 } 1592 }
1630 1593
1631 bool transitWasReset = false; 1594 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1595 return agent;
1596 }
1632 1597
1598 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1599 {
1633 try 1600 try
1634 { 1601 {
1635 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1602 AgentData cAgent = new AgentData();
1636
1637 m_log.DebugFormat(
1638 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1639 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1640
1641 Scene m_scene = agent.Scene;
1642
1643 if (!agent.ValidateAttachments())
1644 m_log.DebugFormat(
1645 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1646 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1647
1648 pos = pos + agent.Velocity;
1649 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1650
1651 agent.RemoveFromPhysicalScene();
1652
1653 AgentData cAgent = new AgentData();
1654 agent.CopyTo(cAgent); 1603 agent.CopyTo(cAgent);
1655 cAgent.Position = pos; 1604 cAgent.Position = pos + agent.Velocity;
1656 if (isFlying) 1605 if (isFlying)
1657 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1606 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1658 1607
@@ -1662,7 +1611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1662 // Beyond this point, extra cleanup is needed beyond removing transit state 1611 // Beyond this point, extra cleanup is needed beyond removing transit state
1663 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1612 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1664 1613
1665 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1614 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1666 { 1615 {
1667 // region doesn't take it 1616 // region doesn't take it
1668 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1617 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1674,88 +1623,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1674 ReInstantiateScripts(agent); 1623 ReInstantiateScripts(agent);
1675 agent.AddToPhysicalScene(isFlying); 1624 agent.AddToPhysicalScene(isFlying);
1676 1625
1677 return agent; 1626 return false;
1678 } 1627 }
1679 1628
1680 //m_log.Debug("BEFORE CROSS"); 1629 }
1681 //Scene.DumpChildrenSeeds(UUID); 1630 catch (Exception e)
1682 //DumpKnownRegions(); 1631 {
1683 string agentcaps; 1632 m_log.ErrorFormat(
1684 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1633 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1685 { 1634 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1686 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1687 neighbourRegion.RegionHandle);
1688 return agent;
1689 }
1690 1635
1691 // No turning back 1636 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1692 agent.IsChildAgent = true; 1637 return false;
1638 }
1693 1639
1694 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1640 return true;
1641 }
1695 1642
1696 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1643 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1644 bool isFlying, string version)
1645 {
1646 agent.ControllingClient.RequestClientInfo();
1697 1647
1698 if (m_eqModule != null) 1648 string agentcaps;
1699 { 1649 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1700 m_eqModule.CrossRegion( 1650 {
1701 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1651 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1702 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1652 neighbourRegion.RegionHandle);
1703 } 1653 return;
1704 else 1654 }
1705 {
1706 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1707 capsPath);
1708 }
1709 1655
1710 // SUCCESS! 1656 // No turning back
1711 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1657 agent.IsChildAgent = true;
1712 1658
1713 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1659 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1714 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1715 1660
1716 agent.MakeChildAgent(); 1661 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1717 1662
1718 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1663 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1719 // but not sure yet what the side effects would be. 1664
1720 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1665 if (m_eqModule != null)
1721 transitWasReset = true; 1666 {
1667 m_eqModule.CrossRegion(
1668 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1669 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1670 }
1671 else
1672 {
1673 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1674 capsPath);
1675 }
1722 1676
1723 // now we have a child agent in this region. Request all interesting data about other (root) agents 1677 // SUCCESS!
1724 agent.SendOtherAgentsAvatarDataToMe(); 1678 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1725 agent.SendOtherAgentsAppearanceToMe();
1726 1679
1727 // Backwards compatibility. Best effort 1680 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1728 if (version == "Unknown" || version == string.Empty) 1681 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1729 {
1730 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1731 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1732 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1733 }
1734 1682
1735 // Next, let's close the child agent connections that are too far away. 1683 agent.MakeChildAgent();
1736 agent.CloseChildAgents(neighbourx, neighboury);
1737 1684
1738 AgentHasMovedAway(agent, false); 1685 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1739 1686 // but not sure yet what the side effects would be.
1740 //m_log.Debug("AFTER CROSS"); 1687 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1741 //Scene.DumpChildrenSeeds(UUID);
1742 //DumpKnownRegions();
1743 }
1744 catch (Exception e)
1745 {
1746 m_log.ErrorFormat(
1747 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1748 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1749 1688
1750 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1689 // now we have a child agent in this region. Request all interesting data about other (root) agents
1751 } 1690 agent.SendOtherAgentsAvatarDataToMe();
1752 finally 1691 agent.SendOtherAgentsAppearanceToMe();
1692
1693 // Backwards compatibility. Best effort
1694 if (version == "Unknown" || version == string.Empty)
1753 { 1695 {
1754 if (!transitWasReset) 1696 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1755 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1697 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1698 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1756 } 1699 }
1757 1700
1758 return agent; 1701 // Next, let's close the child agent connections that are too far away.
1702 uint neighbourx;
1703 uint neighboury;
1704
1705 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1706
1707 neighbourx /= Constants.RegionSize;
1708 neighboury /= Constants.RegionSize;
1709
1710 agent.CloseChildAgents(neighbourx, neighboury);
1711
1712 AgentHasMovedAway(agent, false);
1713
1714 // the user may change their profile information in other region,
1715 // so the userinfo in UserProfileCache is not reliable any more, delete it
1716 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1717// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1718// {
1719// m_log.DebugFormat(
1720// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1721// }
1722
1723 //m_log.Debug("AFTER CROSS");
1724 //Scene.DumpChildrenSeeds(UUID);
1725 //DumpKnownRegions();
1726
1727 return;
1759 } 1728 }
1760 1729
1761 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1730 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1826,10 +1795,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1826 agent.Id0 = currentAgentCircuit.Id0; 1795 agent.Id0 = currentAgentCircuit.Id0;
1827 } 1796 }
1828 1797
1829 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1798 IPEndPoint external = region.ExternalEndPoint;
1830 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1799 if (external != null)
1800 {
1801 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1802 d.BeginInvoke(sp, agent, region, external, true,
1831 InformClientOfNeighbourCompleted, 1803 InformClientOfNeighbourCompleted,
1832 d); 1804 d);
1805 }
1833 } 1806 }
1834 #endregion 1807 #endregion
1835 1808
@@ -2426,30 +2399,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2426 Utils.LongToUInts(newRegionHandle, out x, out y); 2399 Utils.LongToUInts(newRegionHandle, out x, out y);
2427 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2400 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2428 2401
2429 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2402 if (destination != null)
2430 { 2403 {
2431 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2404 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2405 return; // we did it
2406 }
2432 2407
2433 // We are going to move the object back to the old position so long as the old position 2408 // no one or failed lets go back and tell physics to go on
2434 // is in the region 2409 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2435 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2410 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2436 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2411 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2437 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2438 2412
2439 grp.RootPart.GroupPosition = oldGroupPosition; 2413 grp.AbsolutePosition = oldGroupPosition;
2414 grp.Velocity = Vector3.Zero;
2440 2415
2441 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2416 if (grp.RootPart.PhysActor != null)
2442 // move out of the region creating an infinite loop of failed attempts to cross 2417 grp.RootPart.PhysActor.CrossingFailure();
2443 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2444 2418
2445 if (grp.RootPart.KeyframeMotion != null) 2419 if (grp.RootPart.KeyframeMotion != null)
2446 grp.RootPart.KeyframeMotion.CrossingFailure(); 2420 grp.RootPart.KeyframeMotion.CrossingFailure();
2447 2421
2448 grp.ScheduleGroupForFullUpdate(); 2422 grp.ScheduleGroupForFullUpdate();
2449 }
2450 } 2423 }
2451 2424
2452 2425
2426
2453 /// <summary> 2427 /// <summary>
2454 /// Move the given scene object into a new region 2428 /// Move the given scene object into a new region
2455 /// </summary> 2429 /// </summary>
@@ -2500,17 +2474,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2500 grp, e); 2474 grp, e);
2501 } 2475 }
2502 } 2476 }
2477/*
2478 * done on caller ( not in attachments crossing for now)
2503 else 2479 else
2504 { 2480 {
2481
2505 if (!grp.IsDeleted) 2482 if (!grp.IsDeleted)
2506 { 2483 {
2507 PhysicsActor pa = grp.RootPart.PhysActor; 2484 PhysicsActor pa = grp.RootPart.PhysActor;
2508 if (pa != null) 2485 if (pa != null)
2486 {
2509 pa.CrossingFailure(); 2487 pa.CrossingFailure();
2488 if (grp.RootPart.KeyframeMotion != null)
2489 {
2490 // moved to KeyframeMotion.CrossingFailure
2491// grp.RootPart.Velocity = Vector3.Zero;
2492 grp.RootPart.KeyframeMotion.CrossingFailure();
2493// grp.SendGroupRootTerseUpdate();
2494 }
2495 }
2510 } 2496 }
2511 2497
2512 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2498 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2513 } 2499 }
2500 */
2514 } 2501 }
2515 else 2502 else
2516 { 2503 {