aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs452
1 files changed, 225 insertions, 227 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index aa8a4db..246b253 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -51,7 +51,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] 51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")]
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
@@ -409,7 +410,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
409 /// <param name="sp"></param> 410 /// <param name="sp"></param>
410 /// <param name="position"></param> 411 /// <param name="position"></param>
411 /// <param name="lookAt"></param> 412 /// <param name="lookAt"></param>
412 /// <param name="teleportFlags"></param 413 /// <param name="teleportFlags"></param>
413 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 414 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
414 { 415 {
415 m_log.DebugFormat( 416 m_log.DebugFormat(
@@ -444,11 +445,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
444 position.Z = newPosZ; 445 position.Z = newPosZ;
445 } 446 }
446 447
448 if (sp.Flying)
449 teleportFlags |= (uint)TeleportFlags.IsFlying;
450
447 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 451 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
448 452
449 sp.ControllingClient.SendTeleportStart(teleportFlags); 453 sp.ControllingClient.SendTeleportStart(teleportFlags);
450 454
451 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 455 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
456 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
452 sp.Velocity = Vector3.Zero; 457 sp.Velocity = Vector3.Zero;
453 sp.Teleport(position); 458 sp.Teleport(position);
454 459
@@ -652,8 +657,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
652 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 657 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
653 // it's actually doing a lot of work. 658 // it's actually doing a lot of work.
654 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 659 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
655 660 if (endPoint == null || endPoint.Address == null)
656 if (endPoint.Address == null)
657 { 661 {
658 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 662 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
659 663
@@ -692,6 +696,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
692 // both regions 696 // both regions
693 if (sp.ParentID != (uint)0) 697 if (sp.ParentID != (uint)0)
694 sp.StandUp(); 698 sp.StandUp();
699 else if (sp.Flying)
700 teleportFlags |= (uint)TeleportFlags.IsFlying;
695 701
696 if (DisableInterRegionTeleportCancellation) 702 if (DisableInterRegionTeleportCancellation)
697 teleportFlags |= (uint)TeleportFlags.DisableCancel; 703 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -820,7 +826,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
820 // The EnableSimulator message makes the client establish a connection with the destination 826 // The EnableSimulator message makes the client establish a connection with the destination
821 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the 827 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
822 // correct circuit code. 828 // correct circuit code.
823 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 829 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID,
830 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
831 m_log.DebugFormat("{0} Sent EnableSimulator. regName={1}, size=<{2},{3}>", LogHeader,
832 finalDestination.RegionName, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
824 833
825 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination 834 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
826 // simulator to confirm that it has established communication with the viewer. 835 // simulator to confirm that it has established communication with the viewer.
@@ -830,7 +839,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
830 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly 839 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly
831 // only on TeleportFinish). This is untested for region teleport between different simulators 840 // only on TeleportFinish). This is untested for region teleport between different simulators
832 // though this probably also works. 841 // though this probably also works.
833 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 842 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, finalDestination.RegionHandle,
843 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
834 } 844 }
835 else 845 else
836 { 846 {
@@ -916,7 +926,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
916 // OK, send TPFinish to the client, so that it starts the process of contacting the destination region 926 // OK, send TPFinish to the client, so that it starts the process of contacting the destination region
917 if (m_eqModule != null) 927 if (m_eqModule != null)
918 { 928 {
919 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 929 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
930 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
920 } 931 }
921 else 932 else
922 { 933 {
@@ -1069,7 +1080,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1069 1080
1070 // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid 1081 // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid
1071 if (m_eqModule != null) 1082 if (m_eqModule != null)
1072 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 1083 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
1084 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1073 else 1085 else
1074 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, 1086 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
1075 teleportFlags, capsPath); 1087 teleportFlags, capsPath);
@@ -1319,11 +1331,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1319 1331
1320 #region Teleport Home 1332 #region Teleport Home
1321 1333
1322 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1334 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1323 { 1335 {
1324 TeleportHome(id, client); 1336 TeleportHome(id, client);
1325 } 1337 }
1326 1338
1327 public virtual bool TeleportHome(UUID id, IClientAPI client) 1339 public virtual bool TeleportHome(UUID id, IClientAPI client)
1328 { 1340 {
1329 m_log.DebugFormat( 1341 m_log.DebugFormat(
@@ -1334,6 +1346,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1334 1346
1335 if (uinfo != null) 1347 if (uinfo != null)
1336 { 1348 {
1349 if (uinfo.HomeRegionID == UUID.Zero)
1350 {
1351 // can't find the Home region: Tell viewer and abort
1352 client.SendTeleportFailed("You don't have a home position set.");
1353 return false;
1354 }
1337 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1355 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1338 if (regionInfo == null) 1356 if (regionInfo == null)
1339 { 1357 {
@@ -1353,9 +1371,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1353 } 1371 }
1354 else 1372 else
1355 { 1373 {
1356 m_log.ErrorFormat( 1374 // can't find the Home region: Tell viewer and abort
1357 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1375 client.SendTeleportFailed("Your home region could not be found.");
1358 client.Name, client.AgentId);
1359 } 1376 }
1360 return false; 1377 return false;
1361 } 1378 }
@@ -1365,15 +1382,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1365 1382
1366 #region Agent Crossings 1383 #region Agent Crossings
1367 1384
1368 public bool Cross(ScenePresence agent, bool isFlying) 1385 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1369 { 1386 {
1370 Scene scene = agent.Scene; 1387 version = String.Empty;
1371 Vector3 pos = agent.AbsolutePosition; 1388 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1372 1389
1373// m_log.DebugFormat( 1390// m_log.DebugFormat(
1374// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1391// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1375 1392
1376 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1377 uint neighbourx = scene.RegionInfo.RegionLocX; 1393 uint neighbourx = scene.RegionInfo.RegionLocX;
1378 uint neighboury = scene.RegionInfo.RegionLocY; 1394 uint neighboury = scene.RegionInfo.RegionLocY;
1379 const float boundaryDistance = 1.7f; 1395 const float boundaryDistance = 1.7f;
@@ -1394,52 +1410,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1394 } 1410 }
1395 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1411 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1396 { 1412 {
1397 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1413 neighboury--;
1398 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1414 newpos.Y = Constants.RegionSize - enterDistance;
1399 {
1400 neighboury--;
1401 newpos.Y = Constants.RegionSize - enterDistance;
1402 }
1403 else
1404 {
1405 agent.IsInTransit = true;
1406
1407 neighboury = b.TriggerRegionY;
1408 neighbourx = b.TriggerRegionX;
1409
1410 Vector3 newposition = pos;
1411 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1412 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1413 agent.ControllingClient.SendAgentAlertMessage(
1414 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1415 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1416 return true;
1417 }
1418 }
1419
1420 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1421 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1422 {
1423 neighbourx--;
1424 newpos.X = Constants.RegionSize - enterDistance;
1425 }
1426 else
1427 {
1428 agent.IsInTransit = true;
1429
1430 neighboury = ba.TriggerRegionY;
1431 neighbourx = ba.TriggerRegionX;
1432
1433 Vector3 newposition = pos;
1434 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1435 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1436 agent.ControllingClient.SendAgentAlertMessage(
1437 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1438 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1439
1440 return true;
1441 } 1415 }
1442 1416
1417 neighbourx--;
1418 newpos.X = Constants.RegionSize - enterDistance;
1443 } 1419 }
1444 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1420 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1445 { 1421 {
@@ -1449,26 +1425,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1449 1425
1450 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1426 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1451 { 1427 {
1452 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1428 neighboury--;
1453 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1429 newpos.Y = Constants.RegionSize - enterDistance;
1454 {
1455 neighboury--;
1456 newpos.Y = Constants.RegionSize - enterDistance;
1457 }
1458 else
1459 {
1460 agent.IsInTransit = true;
1461
1462 neighboury = ba.TriggerRegionY;
1463 neighbourx = ba.TriggerRegionX;
1464 Vector3 newposition = pos;
1465 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1466 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1467 agent.ControllingClient.SendAgentAlertMessage(
1468 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1469 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1470 return true;
1471 }
1472 } 1430 }
1473 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1431 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1474 { 1432 {
@@ -1480,25 +1438,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1480 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1438 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1481 { 1439 {
1482 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1440 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1483 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1441 neighboury--;
1484 { 1442 newpos.Y = Constants.RegionSize - enterDistance;
1485 neighboury--;
1486 newpos.Y = Constants.RegionSize - enterDistance;
1487 }
1488 else
1489 {
1490 agent.IsInTransit = true;
1491
1492 neighboury = b.TriggerRegionY;
1493 neighbourx = b.TriggerRegionX;
1494 Vector3 newposition = pos;
1495 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1496 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1497 agent.ControllingClient.SendAgentAlertMessage(
1498 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1499 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1500 return true;
1501 }
1502 } 1443 }
1503 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1444 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1504 { 1445 {
@@ -1532,19 +1473,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1532 } 1473 }
1533 */ 1474 */
1534 1475
1535 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1476 xDest = neighbourx;
1477 yDest = neighboury;
1536 1478
1537 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1479 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1538 1480
1481 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1482
1539 ExpiringCache<ulong, DateTime> r; 1483 ExpiringCache<ulong, DateTime> r;
1540 DateTime banUntil; 1484 DateTime banUntil;
1541 1485
1542 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1486 if (m_bannedRegions.TryGetValue(agentID, out r))
1543 { 1487 {
1544 if (r.TryGetValue(neighbourHandle, out banUntil)) 1488 if (r.TryGetValue(neighbourHandle, out banUntil))
1545 { 1489 {
1546 if (DateTime.Now < banUntil) 1490 if (DateTime.Now < banUntil)
1547 return false; 1491 return null;
1548 r.Remove(neighbourHandle); 1492 r.Remove(neighbourHandle);
1549 } 1493 }
1550 } 1494 }
@@ -1556,28 +1500,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1556 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1500 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1557 1501
1558 string reason; 1502 string reason;
1559 string version; 1503 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1560 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1561 { 1504 {
1562 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1563 if (r == null) 1505 if (r == null)
1564 { 1506 {
1565 r = new ExpiringCache<ulong, DateTime>(); 1507 r = new ExpiringCache<ulong, DateTime>();
1566 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1508 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1567 1509
1568 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1510 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1569 } 1511 }
1570 else 1512 else
1571 { 1513 {
1572 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1514 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1573 } 1515 }
1516 return null;
1517 }
1518
1519 return neighbourRegion;
1520 }
1521
1522 public bool Cross(ScenePresence agent, bool isFlying)
1523 {
1524 uint x;
1525 uint y;
1526 Vector3 newpos;
1527 string version;
1528
1529 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1530 if (neighbourRegion == null)
1531 {
1532 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 return false; 1533 return false;
1575 } 1534 }
1576 1535
1577 agent.IsInTransit = true; 1536 agent.IsInTransit = true;
1578 1537
1579 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1538 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1580 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1539 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1581 1540
1582 return true; 1541 return true;
1583 } 1542 }
@@ -1659,52 +1618,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1659 icon.EndInvoke(iar); 1618 icon.EndInvoke(iar);
1660 } 1619 }
1661 1620
1662 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1621 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1622 {
1623 if (neighbourRegion == null)
1624 return false;
1625
1626 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1627
1628 agent.RemoveFromPhysicalScene();
1629
1630 return true;
1631 }
1663 1632
1664 /// <summary> 1633 /// <summary>
1665 /// This Closes child agents on neighbouring regions 1634 /// This Closes child agents on neighbouring regions
1666 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1635 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1667 /// </summary> 1636 /// </summary>
1668 protected ScenePresence CrossAgentToNewRegionAsync( 1637 public ScenePresence CrossAgentToNewRegionAsync(
1669 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1638 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1670 bool isFlying, string version) 1639 bool isFlying, string version)
1671 { 1640 {
1672 if (neighbourRegion == null) 1641 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1642 {
1643 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1673 return agent; 1644 return agent;
1645 }
1674 1646
1675 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1647 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1676 { 1648 {
1677 m_log.ErrorFormat( 1649 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1678 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1679 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1680 return agent; 1650 return agent;
1681 } 1651 }
1682 1652
1683 bool transitWasReset = false; 1653 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1654 return agent;
1655 }
1684 1656
1657 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1658 {
1685 try 1659 try
1686 { 1660 {
1687 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1661 AgentData cAgent = new AgentData();
1688
1689 m_log.DebugFormat(
1690 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1691 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1692
1693 Scene m_scene = agent.Scene;
1694
1695 if (!agent.ValidateAttachments())
1696 m_log.DebugFormat(
1697 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1698 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1699
1700 pos = pos + agent.Velocity;
1701 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1702
1703 agent.RemoveFromPhysicalScene();
1704
1705 AgentData cAgent = new AgentData();
1706 agent.CopyTo(cAgent); 1662 agent.CopyTo(cAgent);
1707 cAgent.Position = pos; 1663 cAgent.Position = pos + agent.Velocity;
1708 if (isFlying) 1664 if (isFlying)
1709 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1665 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1710 1666
@@ -1714,7 +1670,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1714 // Beyond this point, extra cleanup is needed beyond removing transit state 1670 // Beyond this point, extra cleanup is needed beyond removing transit state
1715 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1671 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1716 1672
1717 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1673 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1718 { 1674 {
1719 // region doesn't take it 1675 // region doesn't take it
1720 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1676 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1726,88 +1682,111 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1726 ReInstantiateScripts(agent); 1682 ReInstantiateScripts(agent);
1727 agent.AddToPhysicalScene(isFlying); 1683 agent.AddToPhysicalScene(isFlying);
1728 1684
1729 return agent; 1685 return false;
1730 } 1686 }
1731 1687
1732 //m_log.Debug("BEFORE CROSS"); 1688 }
1733 //Scene.DumpChildrenSeeds(UUID); 1689 catch (Exception e)
1734 //DumpKnownRegions(); 1690 {
1735 string agentcaps; 1691 m_log.ErrorFormat(
1736 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1692 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1737 { 1693 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1738 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1739 neighbourRegion.RegionHandle);
1740 return agent;
1741 }
1742 1694
1743 // No turning back 1695 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1744 agent.IsChildAgent = true; 1696 return false;
1697 }
1745 1698
1746 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1699 return true;
1700 }
1747 1701
1748 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1702 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1703 bool isFlying, string version)
1704 {
1705 agent.ControllingClient.RequestClientInfo();
1749 1706
1750 if (m_eqModule != null) 1707 string agentcaps;
1751 { 1708 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1752 m_eqModule.CrossRegion( 1709 {
1753 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1710 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1754 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1711 neighbourRegion.RegionHandle);
1755 } 1712 return;
1756 else 1713 }
1757 {
1758 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1759 capsPath);
1760 }
1761 1714
1762 // SUCCESS! 1715 // No turning back
1763 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1716 agent.IsChildAgent = true;
1764 1717
1765 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1718 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1766 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1767 1719
1768 agent.MakeChildAgent(); 1720 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1769 1721
1770 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1722 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1771 // but not sure yet what the side effects would be. 1723
1772 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1724 if (m_eqModule != null)
1773 transitWasReset = true; 1725 {
1726 m_eqModule.CrossRegion(
1727 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */,
1728 neighbourRegion.ExternalEndPoint,
1729 capsPath, agent.UUID, agent.ControllingClient.SessionId,
1730 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1731 }
1732 else
1733 {
1734 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
1735 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1736 capsPath);
1737 }
1774 1738
1775 // now we have a child agent in this region. Request all interesting data about other (root) agents 1739 // SUCCESS!
1776 agent.SendOtherAgentsAvatarDataToMe(); 1740 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1777 agent.SendOtherAgentsAppearanceToMe();
1778 1741
1779 // Backwards compatibility. Best effort 1742 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1780 if (version == "Unknown" || version == string.Empty) 1743 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1781 {
1782 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1783 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1784 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1785 }
1786 1744
1787 // Next, let's close the child agent connections that are too far away. 1745 agent.MakeChildAgent();
1788 agent.CloseChildAgents(neighbourx, neighboury);
1789 1746
1790 AgentHasMovedAway(agent, false); 1747 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1791 1748 // but not sure yet what the side effects would be.
1792 //m_log.Debug("AFTER CROSS"); 1749 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1793 //Scene.DumpChildrenSeeds(UUID);
1794 //DumpKnownRegions();
1795 }
1796 catch (Exception e)
1797 {
1798 m_log.ErrorFormat(
1799 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1800 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1801 1750
1802 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1751 // now we have a child agent in this region. Request all interesting data about other (root) agents
1803 } 1752 agent.SendOtherAgentsAvatarDataToMe();
1804 finally 1753 agent.SendOtherAgentsAppearanceToMe();
1754
1755 // Backwards compatibility. Best effort
1756 if (version == "Unknown" || version == string.Empty)
1805 { 1757 {
1806 if (!transitWasReset) 1758 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1807 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1759 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1760 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1808 } 1761 }
1809 1762
1810 return agent; 1763 // Next, let's close the child agent connections that are too far away.
1764 uint neighbourx;
1765 uint neighboury;
1766
1767 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1768
1769 neighbourx /= Constants.RegionSize;
1770 neighboury /= Constants.RegionSize;
1771
1772 agent.CloseChildAgents(neighbourx, neighboury);
1773
1774 AgentHasMovedAway(agent, false);
1775
1776 // the user may change their profile information in other region,
1777 // so the userinfo in UserProfileCache is not reliable any more, delete it
1778 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1779// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1780// {
1781// m_log.DebugFormat(
1782// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1783// }
1784
1785 //m_log.Debug("AFTER CROSS");
1786 //Scene.DumpChildrenSeeds(UUID);
1787 //DumpKnownRegions();
1788
1789 return;
1811 } 1790 }
1812 1791
1813 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1792 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1878,10 +1857,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1878 agent.Id0 = currentAgentCircuit.Id0; 1857 agent.Id0 = currentAgentCircuit.Id0;
1879 } 1858 }
1880 1859
1881 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1860 IPEndPoint external = region.ExternalEndPoint;
1882 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1861 if (external != null)
1862 {
1863 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1864 d.BeginInvoke(sp, agent, region, external, true,
1883 InformClientOfNeighbourCompleted, 1865 InformClientOfNeighbourCompleted,
1884 d); 1866 d);
1867 }
1885 } 1868 }
1886 #endregion 1869 #endregion
1887 1870
@@ -2114,12 +2097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2114 } 2097 }
2115 #endregion 2098 #endregion
2116 2099
2117 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + 2100 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
2118 "and EstablishAgentCommunication with seed cap {4}", 2101 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
2119 scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); 2102 scene.RegionInfo.RegionName, sp.Name,
2103 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath);
2120 2104
2121 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); 2105 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
2122 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 2106 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
2123 } 2107 }
2124 else 2108 else
2125 { 2109 {
@@ -2478,30 +2462,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2478 Utils.LongToUInts(newRegionHandle, out x, out y); 2462 Utils.LongToUInts(newRegionHandle, out x, out y);
2479 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2463 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2480 2464
2481 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2465 if (destination != null)
2482 { 2466 {
2483 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2467 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2468 return; // we did it
2469 }
2484 2470
2485 // We are going to move the object back to the old position so long as the old position 2471 // no one or failed lets go back and tell physics to go on
2486 // is in the region 2472 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2487 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2473 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2488 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2474 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2489 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2490 2475
2491 grp.RootPart.GroupPosition = oldGroupPosition; 2476 grp.AbsolutePosition = oldGroupPosition;
2477 grp.Velocity = Vector3.Zero;
2492 2478
2493 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2479 if (grp.RootPart.PhysActor != null)
2494 // move out of the region creating an infinite loop of failed attempts to cross 2480 grp.RootPart.PhysActor.CrossingFailure();
2495 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2496 2481
2497 if (grp.RootPart.KeyframeMotion != null) 2482 if (grp.RootPart.KeyframeMotion != null)
2498 grp.RootPart.KeyframeMotion.CrossingFailure(); 2483 grp.RootPart.KeyframeMotion.CrossingFailure();
2499 2484
2500 grp.ScheduleGroupForFullUpdate(); 2485 grp.ScheduleGroupForFullUpdate();
2501 }
2502 } 2486 }
2503 2487
2504 2488
2489
2505 /// <summary> 2490 /// <summary>
2506 /// Move the given scene object into a new region 2491 /// Move the given scene object into a new region
2507 /// </summary> 2492 /// </summary>
@@ -2552,17 +2537,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2552 grp, e); 2537 grp, e);
2553 } 2538 }
2554 } 2539 }
2540/*
2541 * done on caller ( not in attachments crossing for now)
2555 else 2542 else
2556 { 2543 {
2544
2557 if (!grp.IsDeleted) 2545 if (!grp.IsDeleted)
2558 { 2546 {
2559 PhysicsActor pa = grp.RootPart.PhysActor; 2547 PhysicsActor pa = grp.RootPart.PhysActor;
2560 if (pa != null) 2548 if (pa != null)
2549 {
2561 pa.CrossingFailure(); 2550 pa.CrossingFailure();
2551 if (grp.RootPart.KeyframeMotion != null)
2552 {
2553 // moved to KeyframeMotion.CrossingFailure
2554// grp.RootPart.Velocity = Vector3.Zero;
2555 grp.RootPart.KeyframeMotion.CrossingFailure();
2556// grp.SendGroupRootTerseUpdate();
2557 }
2558 }
2562 } 2559 }
2563 2560
2564 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2561 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2565 } 2562 }
2563 */
2566 } 2564 }
2567 else 2565 else
2568 { 2566 {