aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs421
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs32
2 files changed, 214 insertions, 239 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index aa8a4db..ef5239a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -409,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
409 /// <param name="sp"></param> 409 /// <param name="sp"></param>
410 /// <param name="position"></param> 410 /// <param name="position"></param>
411 /// <param name="lookAt"></param> 411 /// <param name="lookAt"></param>
412 /// <param name="teleportFlags"></param 412 /// <param name="teleportFlags"></param>
413 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 413 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
414 { 414 {
415 m_log.DebugFormat( 415 m_log.DebugFormat(
@@ -444,11 +444,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
444 position.Z = newPosZ; 444 position.Z = newPosZ;
445 } 445 }
446 446
447 if (sp.Flying)
448 teleportFlags |= (uint)TeleportFlags.IsFlying;
449
447 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 450 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
448 451
449 sp.ControllingClient.SendTeleportStart(teleportFlags); 452 sp.ControllingClient.SendTeleportStart(teleportFlags);
450 453
451 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 454 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
455 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
452 sp.Velocity = Vector3.Zero; 456 sp.Velocity = Vector3.Zero;
453 sp.Teleport(position); 457 sp.Teleport(position);
454 458
@@ -652,8 +656,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
652 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 656 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
653 // it's actually doing a lot of work. 657 // it's actually doing a lot of work.
654 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 658 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
655 659 if (endPoint == null || endPoint.Address == null)
656 if (endPoint.Address == null)
657 { 660 {
658 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 661 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
659 662
@@ -692,6 +695,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
692 // both regions 695 // both regions
693 if (sp.ParentID != (uint)0) 696 if (sp.ParentID != (uint)0)
694 sp.StandUp(); 697 sp.StandUp();
698 else if (sp.Flying)
699 teleportFlags |= (uint)TeleportFlags.IsFlying;
695 700
696 if (DisableInterRegionTeleportCancellation) 701 if (DisableInterRegionTeleportCancellation)
697 teleportFlags |= (uint)TeleportFlags.DisableCancel; 702 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -1319,11 +1324,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1319 1324
1320 #region Teleport Home 1325 #region Teleport Home
1321 1326
1322 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1327 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1323 { 1328 {
1324 TeleportHome(id, client); 1329 TeleportHome(id, client);
1325 } 1330 }
1326 1331
1327 public virtual bool TeleportHome(UUID id, IClientAPI client) 1332 public virtual bool TeleportHome(UUID id, IClientAPI client)
1328 { 1333 {
1329 m_log.DebugFormat( 1334 m_log.DebugFormat(
@@ -1334,6 +1339,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1334 1339
1335 if (uinfo != null) 1340 if (uinfo != null)
1336 { 1341 {
1342 if (uinfo.HomeRegionID == UUID.Zero)
1343 {
1344 // can't find the Home region: Tell viewer and abort
1345 client.SendTeleportFailed("You don't have a home position set.");
1346 return false;
1347 }
1337 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1348 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1338 if (regionInfo == null) 1349 if (regionInfo == null)
1339 { 1350 {
@@ -1353,9 +1364,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1353 } 1364 }
1354 else 1365 else
1355 { 1366 {
1356 m_log.ErrorFormat( 1367 // 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.", 1368 client.SendTeleportFailed("Your home region could not be found.");
1358 client.Name, client.AgentId);
1359 } 1369 }
1360 return false; 1370 return false;
1361 } 1371 }
@@ -1365,15 +1375,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1365 1375
1366 #region Agent Crossings 1376 #region Agent Crossings
1367 1377
1368 public bool Cross(ScenePresence agent, bool isFlying) 1378 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1369 { 1379 {
1370 Scene scene = agent.Scene; 1380 version = String.Empty;
1371 Vector3 pos = agent.AbsolutePosition; 1381 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1372 1382
1373// m_log.DebugFormat( 1383// m_log.DebugFormat(
1374// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1384// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1375 1385
1376 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1377 uint neighbourx = scene.RegionInfo.RegionLocX; 1386 uint neighbourx = scene.RegionInfo.RegionLocX;
1378 uint neighboury = scene.RegionInfo.RegionLocY; 1387 uint neighboury = scene.RegionInfo.RegionLocY;
1379 const float boundaryDistance = 1.7f; 1388 const float boundaryDistance = 1.7f;
@@ -1394,52 +1403,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1394 } 1403 }
1395 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1404 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1396 { 1405 {
1397 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1406 neighboury--;
1398 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1407 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 } 1408 }
1442 1409
1410 neighbourx--;
1411 newpos.X = Constants.RegionSize - enterDistance;
1443 } 1412 }
1444 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1413 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1445 { 1414 {
@@ -1449,26 +1418,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1449 1418
1450 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1419 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1451 { 1420 {
1452 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1421 neighboury--;
1453 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1422 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 } 1423 }
1473 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1424 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1474 { 1425 {
@@ -1480,25 +1431,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1480 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1431 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1481 { 1432 {
1482 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1433 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1483 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1434 neighboury--;
1484 { 1435 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 } 1436 }
1503 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1437 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1504 { 1438 {
@@ -1532,19 +1466,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1532 } 1466 }
1533 */ 1467 */
1534 1468
1535 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1469 xDest = neighbourx;
1470 yDest = neighboury;
1536 1471
1537 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1472 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1538 1473
1474 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1475
1539 ExpiringCache<ulong, DateTime> r; 1476 ExpiringCache<ulong, DateTime> r;
1540 DateTime banUntil; 1477 DateTime banUntil;
1541 1478
1542 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1479 if (m_bannedRegions.TryGetValue(agentID, out r))
1543 { 1480 {
1544 if (r.TryGetValue(neighbourHandle, out banUntil)) 1481 if (r.TryGetValue(neighbourHandle, out banUntil))
1545 { 1482 {
1546 if (DateTime.Now < banUntil) 1483 if (DateTime.Now < banUntil)
1547 return false; 1484 return null;
1548 r.Remove(neighbourHandle); 1485 r.Remove(neighbourHandle);
1549 } 1486 }
1550 } 1487 }
@@ -1556,28 +1493,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1556 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1493 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1557 1494
1558 string reason; 1495 string reason;
1559 string version; 1496 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 { 1497 {
1562 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1563 if (r == null) 1498 if (r == null)
1564 { 1499 {
1565 r = new ExpiringCache<ulong, DateTime>(); 1500 r = new ExpiringCache<ulong, DateTime>();
1566 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1501 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1567 1502
1568 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1503 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1569 } 1504 }
1570 else 1505 else
1571 { 1506 {
1572 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1507 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1573 } 1508 }
1509 return null;
1510 }
1511
1512 return neighbourRegion;
1513 }
1514
1515 public bool Cross(ScenePresence agent, bool isFlying)
1516 {
1517 uint x;
1518 uint y;
1519 Vector3 newpos;
1520 string version;
1521
1522 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1523 if (neighbourRegion == null)
1524 {
1525 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 return false; 1526 return false;
1575 } 1527 }
1576 1528
1577 agent.IsInTransit = true; 1529 agent.IsInTransit = true;
1578 1530
1579 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1531 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1580 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1532 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1581 1533
1582 return true; 1534 return true;
1583 } 1535 }
@@ -1659,52 +1611,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1659 icon.EndInvoke(iar); 1611 icon.EndInvoke(iar);
1660 } 1612 }
1661 1613
1662 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1614 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1615 {
1616 if (neighbourRegion == null)
1617 return false;
1618
1619 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1620
1621 agent.RemoveFromPhysicalScene();
1622
1623 return true;
1624 }
1663 1625
1664 /// <summary> 1626 /// <summary>
1665 /// This Closes child agents on neighbouring regions 1627 /// This Closes child agents on neighbouring regions
1666 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1628 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1667 /// </summary> 1629 /// </summary>
1668 protected ScenePresence CrossAgentToNewRegionAsync( 1630 public ScenePresence CrossAgentToNewRegionAsync(
1669 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1631 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1670 bool isFlying, string version) 1632 bool isFlying, string version)
1671 { 1633 {
1672 if (neighbourRegion == null) 1634 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1635 {
1636 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1673 return agent; 1637 return agent;
1638 }
1674 1639
1675 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1640 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1676 { 1641 {
1677 m_log.ErrorFormat( 1642 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; 1643 return agent;
1681 } 1644 }
1682 1645
1683 bool transitWasReset = false; 1646 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1647 return agent;
1648 }
1684 1649
1650 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1651 {
1685 try 1652 try
1686 { 1653 {
1687 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1654 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); 1655 agent.CopyTo(cAgent);
1707 cAgent.Position = pos; 1656 cAgent.Position = pos + agent.Velocity;
1708 if (isFlying) 1657 if (isFlying)
1709 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1658 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1710 1659
@@ -1714,7 +1663,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1714 // Beyond this point, extra cleanup is needed beyond removing transit state 1663 // Beyond this point, extra cleanup is needed beyond removing transit state
1715 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1664 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1716 1665
1717 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1666 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1718 { 1667 {
1719 // region doesn't take it 1668 // region doesn't take it
1720 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1669 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1726,88 +1675,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1726 ReInstantiateScripts(agent); 1675 ReInstantiateScripts(agent);
1727 agent.AddToPhysicalScene(isFlying); 1676 agent.AddToPhysicalScene(isFlying);
1728 1677
1729 return agent; 1678 return false;
1730 } 1679 }
1731 1680
1732 //m_log.Debug("BEFORE CROSS"); 1681 }
1733 //Scene.DumpChildrenSeeds(UUID); 1682 catch (Exception e)
1734 //DumpKnownRegions(); 1683 {
1735 string agentcaps; 1684 m_log.ErrorFormat(
1736 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1685 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1737 { 1686 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 1687
1743 // No turning back 1688 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1744 agent.IsChildAgent = true; 1689 return false;
1690 }
1745 1691
1746 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1692 return true;
1693 }
1747 1694
1748 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1695 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1696 bool isFlying, string version)
1697 {
1698 agent.ControllingClient.RequestClientInfo();
1749 1699
1750 if (m_eqModule != null) 1700 string agentcaps;
1751 { 1701 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1752 m_eqModule.CrossRegion( 1702 {
1753 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1703 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1754 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1704 neighbourRegion.RegionHandle);
1755 } 1705 return;
1756 else 1706 }
1757 {
1758 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1759 capsPath);
1760 }
1761 1707
1762 // SUCCESS! 1708 // No turning back
1763 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1709 agent.IsChildAgent = true;
1764 1710
1765 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1711 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1766 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1767 1712
1768 agent.MakeChildAgent(); 1713 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1769 1714
1770 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1715 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1771 // but not sure yet what the side effects would be. 1716
1772 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1717 if (m_eqModule != null)
1773 transitWasReset = true; 1718 {
1719 m_eqModule.CrossRegion(
1720 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1721 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1722 }
1723 else
1724 {
1725 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1726 capsPath);
1727 }
1774 1728
1775 // now we have a child agent in this region. Request all interesting data about other (root) agents 1729 // SUCCESS!
1776 agent.SendOtherAgentsAvatarDataToMe(); 1730 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1777 agent.SendOtherAgentsAppearanceToMe();
1778 1731
1779 // Backwards compatibility. Best effort 1732 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1780 if (version == "Unknown" || version == string.Empty) 1733 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 1734
1787 // Next, let's close the child agent connections that are too far away. 1735 agent.MakeChildAgent();
1788 agent.CloseChildAgents(neighbourx, neighboury);
1789 1736
1790 AgentHasMovedAway(agent, false); 1737 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1791 1738 // but not sure yet what the side effects would be.
1792 //m_log.Debug("AFTER CROSS"); 1739 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 1740
1802 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1741 // now we have a child agent in this region. Request all interesting data about other (root) agents
1803 } 1742 agent.SendOtherAgentsAvatarDataToMe();
1804 finally 1743 agent.SendOtherAgentsAppearanceToMe();
1744
1745 // Backwards compatibility. Best effort
1746 if (version == "Unknown" || version == string.Empty)
1805 { 1747 {
1806 if (!transitWasReset) 1748 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1807 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1749 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1750 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1808 } 1751 }
1809 1752
1810 return agent; 1753 // Next, let's close the child agent connections that are too far away.
1754 uint neighbourx;
1755 uint neighboury;
1756
1757 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1758
1759 neighbourx /= Constants.RegionSize;
1760 neighboury /= Constants.RegionSize;
1761
1762 agent.CloseChildAgents(neighbourx, neighboury);
1763
1764 AgentHasMovedAway(agent, false);
1765
1766 // the user may change their profile information in other region,
1767 // so the userinfo in UserProfileCache is not reliable any more, delete it
1768 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1769// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1770// {
1771// m_log.DebugFormat(
1772// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1773// }
1774
1775 //m_log.Debug("AFTER CROSS");
1776 //Scene.DumpChildrenSeeds(UUID);
1777 //DumpKnownRegions();
1778
1779 return;
1811 } 1780 }
1812 1781
1813 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1782 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1878,10 +1847,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1878 agent.Id0 = currentAgentCircuit.Id0; 1847 agent.Id0 = currentAgentCircuit.Id0;
1879 } 1848 }
1880 1849
1881 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1850 IPEndPoint external = region.ExternalEndPoint;
1882 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1851 if (external != null)
1852 {
1853 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1854 d.BeginInvoke(sp, agent, region, external, true,
1883 InformClientOfNeighbourCompleted, 1855 InformClientOfNeighbourCompleted,
1884 d); 1856 d);
1857 }
1885 } 1858 }
1886 #endregion 1859 #endregion
1887 1860
@@ -2478,30 +2451,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2478 Utils.LongToUInts(newRegionHandle, out x, out y); 2451 Utils.LongToUInts(newRegionHandle, out x, out y);
2479 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2452 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2480 2453
2481 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2454 if (destination != null)
2482 { 2455 {
2483 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2456 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2457 return; // we did it
2458 }
2484 2459
2485 // We are going to move the object back to the old position so long as the old position 2460 // no one or failed lets go back and tell physics to go on
2486 // is in the region 2461 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); 2462 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); 2463 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2489 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2490 2464
2491 grp.RootPart.GroupPosition = oldGroupPosition; 2465 grp.AbsolutePosition = oldGroupPosition;
2466 grp.Velocity = Vector3.Zero;
2492 2467
2493 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2468 if (grp.RootPart.PhysActor != null)
2494 // move out of the region creating an infinite loop of failed attempts to cross 2469 grp.RootPart.PhysActor.CrossingFailure();
2495 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2496 2470
2497 if (grp.RootPart.KeyframeMotion != null) 2471 if (grp.RootPart.KeyframeMotion != null)
2498 grp.RootPart.KeyframeMotion.CrossingFailure(); 2472 grp.RootPart.KeyframeMotion.CrossingFailure();
2499 2473
2500 grp.ScheduleGroupForFullUpdate(); 2474 grp.ScheduleGroupForFullUpdate();
2501 }
2502 } 2475 }
2503 2476
2504 2477
2478
2505 /// <summary> 2479 /// <summary>
2506 /// Move the given scene object into a new region 2480 /// Move the given scene object into a new region
2507 /// </summary> 2481 /// </summary>
@@ -2552,17 +2526,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2552 grp, e); 2526 grp, e);
2553 } 2527 }
2554 } 2528 }
2529/*
2530 * done on caller ( not in attachments crossing for now)
2555 else 2531 else
2556 { 2532 {
2533
2557 if (!grp.IsDeleted) 2534 if (!grp.IsDeleted)
2558 { 2535 {
2559 PhysicsActor pa = grp.RootPart.PhysActor; 2536 PhysicsActor pa = grp.RootPart.PhysActor;
2560 if (pa != null) 2537 if (pa != null)
2538 {
2561 pa.CrossingFailure(); 2539 pa.CrossingFailure();
2540 if (grp.RootPart.KeyframeMotion != null)
2541 {
2542 // moved to KeyframeMotion.CrossingFailure
2543// grp.RootPart.Velocity = Vector3.Zero;
2544 grp.RootPart.KeyframeMotion.CrossingFailure();
2545// grp.SendGroupRootTerseUpdate();
2546 }
2547 }
2562 } 2548 }
2563 2549
2564 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2550 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2565 } 2551 }
2552 */
2566 } 2553 }
2567 else 2554 else
2568 { 2555 {
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 1c43a25..1949a90 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
35 35
36namespace OpenSim.Region.Framework.Interfaces 36namespace OpenSim.Region.Framework.Interfaces
37{ 37{
38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
39
38 public interface IEntityTransferModule 40 public interface IEntityTransferModule
39 { 41 {
40 /// <summary> 42 /// <summary>
@@ -50,30 +52,11 @@ namespace OpenSim.Region.Framework.Interfaces
50 /// <param name='teleportFlags'></param> 52 /// <param name='teleportFlags'></param>
51 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); 53 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags);
52 54
53 /// <summary>
54 /// Teleport an agent directly to a given region without checking whether the region should be subsituted.
55 /// </summary>
56 /// <remarks>
57 /// Please use Teleport() instead unless you know exactly what you're doing.
58 /// Do not use for same region teleports.
59 /// </remarks>
60 /// <param name='sp'></param>
61 /// <param name='reg'></param>
62 /// <param name='finalDestination'>/param>
63 /// <param name='position'></param>
64 /// <param name='lookAt'></param>
65 /// <param name='teleportFlags'></param>
66 void DoTeleport(
67 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
68 Vector3 position, Vector3 lookAt, uint teleportFlags);
69
70 /// <summary>
71 /// Teleports the agent for the given client to their home destination.
72 /// </summary>
73 /// <param name='id'></param>
74 /// <param name='client'></param>
75 bool TeleportHome(UUID id, IClientAPI client); 55 bool TeleportHome(UUID id, IClientAPI client);
76 56
57 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
58 Vector3 position, Vector3 lookAt, uint teleportFlags);
59
77 /// <summary> 60 /// <summary>
78 /// Show whether the given agent is being teleported. 61 /// Show whether the given agent is being teleported.
79 /// </summary> 62 /// </summary>
@@ -89,7 +72,12 @@ namespace OpenSim.Region.Framework.Interfaces
89 72
90 void EnableChildAgent(ScenePresence agent, GridRegion region); 73 void EnableChildAgent(ScenePresence agent, GridRegion region);
91 74
75 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
76
92 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 77 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
78
79 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
80
93 } 81 }
94 82
95 public interface IUserAgentVerificationModule 83 public interface IUserAgentVerificationModule