diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 738 |
1 files changed, 235 insertions, 503 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 1bb3e3b..4954cd9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -410,7 +410,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
410 | /// <param name="sp"></param> | 410 | /// <param name="sp"></param> |
411 | /// <param name="position"></param> | 411 | /// <param name="position"></param> |
412 | /// <param name="lookAt"></param> | 412 | /// <param name="lookAt"></param> |
413 | /// <param name="teleportFlags"></param | 413 | /// <param name="teleportFlags"></param> |
414 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | 414 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) |
415 | { | 415 | { |
416 | m_log.DebugFormat( | 416 | m_log.DebugFormat( |
@@ -442,11 +442,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
442 | position.Z = newPosZ; | 442 | position.Z = newPosZ; |
443 | } | 443 | } |
444 | 444 | ||
445 | if (sp.Flying) | ||
446 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
447 | |||
445 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | 448 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
446 | 449 | ||
447 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 450 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
448 | 451 | ||
449 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 452 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
453 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | ||
450 | sp.Velocity = Vector3.Zero; | 454 | sp.Velocity = Vector3.Zero; |
451 | sp.Teleport(position); | 455 | sp.Teleport(position); |
452 | 456 | ||
@@ -649,8 +653,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
649 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 653 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
650 | // it's actually doing a lot of work. | 654 | // it's actually doing a lot of work. |
651 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 655 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
652 | 656 | if (endPoint == null || endPoint.Address == null) | |
653 | if (endPoint.Address == null) | ||
654 | { | 657 | { |
655 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 658 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
656 | 659 | ||
@@ -689,6 +692,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
689 | // both regions | 692 | // both regions |
690 | if (sp.ParentID != (uint)0) | 693 | if (sp.ParentID != (uint)0) |
691 | sp.StandUp(); | 694 | sp.StandUp(); |
695 | else if (sp.Flying) | ||
696 | teleportFlags |= (uint)TeleportFlags.IsFlying; | ||
692 | 697 | ||
693 | if (DisableInterRegionTeleportCancellation) | 698 | if (DisableInterRegionTeleportCancellation) |
694 | teleportFlags |= (uint)TeleportFlags.DisableCancel; | 699 | teleportFlags |= (uint)TeleportFlags.DisableCancel; |
@@ -1316,11 +1321,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1316 | 1321 | ||
1317 | #region Teleport Home | 1322 | #region Teleport Home |
1318 | 1323 | ||
1319 | public virtual void TriggerTeleportHome(UUID id, IClientAPI client) | 1324 | public virtual void TriggerTeleportHome(UUID id, IClientAPI client) |
1320 | { | 1325 | { |
1321 | TeleportHome(id, client); | 1326 | TeleportHome(id, client); |
1322 | } | 1327 | } |
1323 | 1328 | ||
1324 | public virtual bool TeleportHome(UUID id, IClientAPI client) | 1329 | public virtual bool TeleportHome(UUID id, IClientAPI client) |
1325 | { | 1330 | { |
1326 | m_log.DebugFormat( | 1331 | m_log.DebugFormat( |
@@ -1331,6 +1336,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1331 | 1336 | ||
1332 | if (uinfo != null) | 1337 | if (uinfo != null) |
1333 | { | 1338 | { |
1339 | if (uinfo.HomeRegionID == UUID.Zero) | ||
1340 | { | ||
1341 | // can't find the Home region: Tell viewer and abort | ||
1342 | m_log.ErrorFormat("{0} No grid user info found for {1} {2}. Cannot send home.", | ||
1343 | LogHeader, client.Name, client.AgentId); | ||
1344 | client.SendTeleportFailed("You don't have a home position set."); | ||
1345 | return false; | ||
1346 | } | ||
1334 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 1347 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
1335 | if (regionInfo == null) | 1348 | if (regionInfo == null) |
1336 | { | 1349 | { |
@@ -1350,9 +1363,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1350 | } | 1363 | } |
1351 | else | 1364 | else |
1352 | { | 1365 | { |
1353 | m_log.ErrorFormat( | 1366 | // can't find the Home region: Tell viewer and abort |
1354 | "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", | 1367 | client.SendTeleportFailed("Your home region could not be found."); |
1355 | client.Name, client.AgentId); | ||
1356 | } | 1368 | } |
1357 | return false; | 1369 | return false; |
1358 | } | 1370 | } |
@@ -1362,177 +1374,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1362 | 1374 | ||
1363 | #region Agent Crossings | 1375 | #region Agent Crossings |
1364 | 1376 | ||
1365 | public bool Cross(ScenePresence agent, bool isFlying) | 1377 | // Given a position relative to the current region (which has previously been tested to |
1378 | // see that it is actually outside the current region), find the new region that the | ||
1379 | // point is actually in. | ||
1380 | // Returns the coordinates and information of the new region or 'null' of it doesn't exist. | ||
1381 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) | ||
1366 | { | 1382 | { |
1367 | Scene scene = agent.Scene; | 1383 | version = String.Empty; |
1368 | Vector3 pos = agent.AbsolutePosition; | 1384 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
1369 | 1385 | ||
1370 | // m_log.DebugFormat( | 1386 | // m_log.DebugFormat( |
1371 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); | 1387 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); |
1372 | /* | ||
1373 | |||
1374 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
1375 | uint neighbourx = scene.RegionInfo.LegacyRegionLocX; | ||
1376 | uint neighboury = scene.RegionInfo.LegacyRegionLocY; | ||
1377 | const float boundaryDistance = 1.7f; | ||
1378 | Vector3 northCross = new Vector3(0, boundaryDistance, 0); | ||
1379 | Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); | ||
1380 | Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); | ||
1381 | Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); | ||
1382 | |||
1383 | // distance into new region to place avatar | ||
1384 | const float enterDistance = 0.5f; | ||
1385 | |||
1386 | if (scene.TestBorderCross(pos + westCross, Cardinals.W)) | ||
1387 | { | ||
1388 | if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | ||
1389 | { | ||
1390 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | ||
1391 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | ||
1392 | } | ||
1393 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | ||
1394 | { | ||
1395 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | ||
1396 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | ||
1397 | { | ||
1398 | neighboury--; | ||
1399 | newpos.Y = Constants.RegionSize - enterDistance; | ||
1400 | } | ||
1401 | else | ||
1402 | { | ||
1403 | agent.IsInTransit = true; | ||
1404 | |||
1405 | neighboury = b.TriggerRegionY; | ||
1406 | neighbourx = b.TriggerRegionX; | ||
1407 | |||
1408 | Vector3 newposition = pos; | ||
1409 | newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize; | ||
1410 | newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize; | ||
1411 | agent.ControllingClient.SendAgentAlertMessage( | ||
1412 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
1413 | InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
1414 | return true; | ||
1415 | } | ||
1416 | } | ||
1417 | |||
1418 | Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); | ||
1419 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
1420 | { | ||
1421 | neighbourx--; | ||
1422 | newpos.X = Constants.RegionSize - enterDistance; | ||
1423 | } | ||
1424 | else | ||
1425 | { | ||
1426 | agent.IsInTransit = true; | ||
1427 | |||
1428 | neighboury = ba.TriggerRegionY; | ||
1429 | neighbourx = ba.TriggerRegionX; | ||
1430 | |||
1431 | Vector3 newposition = pos; | ||
1432 | newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize; | ||
1433 | newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize; | ||
1434 | agent.ControllingClient.SendAgentAlertMessage( | ||
1435 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
1436 | InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
1437 | |||
1438 | return true; | ||
1439 | } | ||
1440 | |||
1441 | } | ||
1442 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | ||
1443 | { | ||
1444 | Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E); | ||
1445 | neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | ||
1446 | newpos.X = enterDistance; | ||
1447 | |||
1448 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | ||
1449 | { | ||
1450 | Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | ||
1451 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
1452 | { | ||
1453 | neighboury--; | ||
1454 | newpos.Y = Constants.RegionSize - enterDistance; | ||
1455 | } | ||
1456 | else | ||
1457 | { | ||
1458 | agent.IsInTransit = true; | ||
1459 | |||
1460 | neighboury = ba.TriggerRegionY; | ||
1461 | neighbourx = ba.TriggerRegionX; | ||
1462 | Vector3 newposition = pos; | ||
1463 | newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize; | ||
1464 | newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize; | ||
1465 | agent.ControllingClient.SendAgentAlertMessage( | ||
1466 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
1467 | InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
1468 | return true; | ||
1469 | } | ||
1470 | } | ||
1471 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | ||
1472 | { | ||
1473 | Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | ||
1474 | neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); | ||
1475 | newpos.Y = enterDistance; | ||
1476 | } | ||
1477 | } | ||
1478 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | ||
1479 | { | ||
1480 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | ||
1481 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | ||
1482 | { | ||
1483 | neighboury--; | ||
1484 | newpos.Y = Constants.RegionSize - enterDistance; | ||
1485 | } | ||
1486 | else | ||
1487 | { | ||
1488 | agent.IsInTransit = true; | ||
1489 | |||
1490 | neighboury = b.TriggerRegionY; | ||
1491 | neighbourx = b.TriggerRegionX; | ||
1492 | Vector3 newposition = pos; | ||
1493 | newposition.X += (scene.RegionInfo.LegacyRegionLocX - neighbourx) * Constants.RegionSize; | ||
1494 | newposition.Y += (scene.RegionInfo.LegacyRegionLocY - neighboury) * Constants.RegionSize; | ||
1495 | agent.ControllingClient.SendAgentAlertMessage( | ||
1496 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
1497 | InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
1498 | return true; | ||
1499 | } | ||
1500 | } | ||
1501 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | ||
1502 | { | ||
1503 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | ||
1504 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | ||
1505 | newpos.Y = enterDistance; | ||
1506 | } | ||
1507 | */ | ||
1508 | |||
1509 | /* | ||
1510 | |||
1511 | if (pos.X < boundaryDistance) //West | ||
1512 | { | ||
1513 | neighbourx--; | ||
1514 | newpos.X = Constants.RegionSize - enterDistance; | ||
1515 | } | ||
1516 | else if (pos.X > Constants.RegionSize - boundaryDistance) // East | ||
1517 | { | ||
1518 | neighbourx++; | ||
1519 | newpos.X = enterDistance; | ||
1520 | } | ||
1521 | |||
1522 | if (pos.Y < boundaryDistance) // South | ||
1523 | { | ||
1524 | neighboury--; | ||
1525 | newpos.Y = Constants.RegionSize - enterDistance; | ||
1526 | } | ||
1527 | else if (pos.Y > Constants.RegionSize - boundaryDistance) // North | ||
1528 | { | ||
1529 | neighboury++; | ||
1530 | newpos.Y = enterDistance; | ||
1531 | } | ||
1532 | */ | ||
1533 | 1388 | ||
1534 | double presenceWorldX = (double)scene.RegionInfo.RegionLocX + pos.X; | 1389 | // Compute world location of the object's position |
1535 | double presenceWorldY = (double)scene.RegionInfo.RegionLocY + pos.Y; | 1390 | double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; |
1391 | double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; | ||
1536 | 1392 | ||
1537 | // Call the grid service to lookup the region containing the new position. | 1393 | // Call the grid service to lookup the region containing the new position. |
1538 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, | 1394 | GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, |
@@ -1540,63 +1396,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1540 | 1396 | ||
1541 | if (neighbourRegion != null) | 1397 | if (neighbourRegion != null) |
1542 | { | 1398 | { |
1543 | Vector3 newRegionRelativeObjectPosition = new Vector3( | 1399 | // Compute the entity's position relative to the new region |
1544 | (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), | 1400 | newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), |
1545 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), | 1401 | (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), |
1546 | pos.Z); | 1402 | pos.Z); |
1547 | agent.ControllingClient.SendAgentAlertMessage( | 1403 | |
1548 | String.Format("Moving you to region {0},{1}", neighbourRegion.RegionCoordX, neighbourRegion.RegionCoordY), false); | 1404 | // Check if banned from destination region. |
1549 | InformClientToInitiateTeleportToLocation(agent, (uint)neighbourRegion.RegionCoordX, (uint)neighbourRegion.RegionCoordY, | ||
1550 | newRegionRelativeObjectPosition, scene); | ||
1551 | |||
1552 | ExpiringCache<ulong, DateTime> r; | 1405 | ExpiringCache<ulong, DateTime> r; |
1553 | DateTime banUntil; | 1406 | DateTime banUntil; |
1554 | 1407 | if (m_bannedRegions.TryGetValue(agentID, out r)) | |
1555 | if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) | 1408 | { |
1556 | { | 1409 | if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil)) |
1557 | if (r.TryGetValue(neighbourRegion.RegionHandle, out banUntil)) | 1410 | { |
1558 | { | 1411 | if (DateTime.Now < banUntil) |
1559 | if (DateTime.Now < banUntil) | 1412 | { |
1560 | return false; | 1413 | // If we're banned from the destination, we just can't go there. |
1561 | r.Remove(neighbourRegion.RegionHandle); | 1414 | neighbourRegion = null; |
1562 | } | 1415 | } |
1563 | } | 1416 | r.Remove(neighbourRegion.RegionHandle); |
1564 | else | 1417 | } |
1565 | { | 1418 | } |
1566 | r = null; | 1419 | else |
1420 | { | ||
1421 | r = null; | ||
1567 | } | 1422 | } |
1568 | 1423 | ||
1424 | // Check to see if we have access to the target region. | ||
1569 | string reason; | 1425 | string reason; |
1570 | string version; | 1426 | if (neighbourRegion != null |
1571 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newRegionRelativeObjectPosition, out version, out reason)) | 1427 | && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
1572 | { | 1428 | { |
1573 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
1574 | if (r == null) | 1429 | if (r == null) |
1575 | { | 1430 | { |
1576 | r = new ExpiringCache<ulong, DateTime>(); | 1431 | r = new ExpiringCache<ulong, DateTime>(); |
1577 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 1432 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1578 | 1433 | ||
1579 | m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); | 1434 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); |
1580 | } | 1435 | } |
1581 | else | 1436 | else |
1582 | { | 1437 | { |
1583 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 1438 | r.Add(neighbourRegion.RegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
1584 | } | 1439 | } |
1585 | return false; | 1440 | neighbourRegion = null; |
1586 | } | 1441 | } |
1442 | } | ||
1587 | 1443 | ||
1588 | agent.IsInTransit = true; | 1444 | return neighbourRegion; |
1445 | } | ||
1589 | 1446 | ||
1590 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 1447 | public bool Cross(ScenePresence agent, bool isFlying) |
1591 | d.BeginInvoke(agent, newRegionRelativeObjectPosition, | 1448 | { |
1592 | (uint)neighbourRegion.RegionLocX, (uint)neighbourRegion.RegionLocY, | 1449 | uint x; |
1593 | neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | 1450 | uint y; |
1594 | } | 1451 | Vector3 newpos; |
1595 | else | 1452 | string version; |
1453 | |||
1454 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos); | ||
1455 | if (neighbourRegion == null) | ||
1596 | { | 1456 | { |
1597 | m_log.ErrorFormat("{0} Cross(sp). Did not find target region. SP.AbsolutePosition={1}", LogHeader, pos); | 1457 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); |
1458 | return false; | ||
1598 | } | 1459 | } |
1599 | 1460 | ||
1461 | agent.IsInTransit = true; | ||
1462 | |||
1463 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | ||
1464 | d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | ||
1465 | |||
1600 | return true; | 1466 | return true; |
1601 | } | 1467 | } |
1602 | 1468 | ||
@@ -1677,52 +1543,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1677 | icon.EndInvoke(iar); | 1543 | icon.EndInvoke(iar); |
1678 | } | 1544 | } |
1679 | 1545 | ||
1680 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | 1546 | public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) |
1547 | { | ||
1548 | if (neighbourRegion == null) | ||
1549 | return false; | ||
1550 | |||
1551 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1552 | |||
1553 | agent.RemoveFromPhysicalScene(); | ||
1554 | |||
1555 | return true; | ||
1556 | } | ||
1681 | 1557 | ||
1682 | /// <summary> | 1558 | /// <summary> |
1683 | /// This Closes child agents on neighbouring regions | 1559 | /// This Closes child agents on neighbouring regions |
1684 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 1560 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
1685 | /// </summary> | 1561 | /// </summary> |
1686 | protected ScenePresence CrossAgentToNewRegionAsync( | 1562 | public ScenePresence CrossAgentToNewRegionAsync( |
1687 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1563 | ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1688 | bool isFlying, string version) | 1564 | bool isFlying, string version) |
1689 | { | 1565 | { |
1690 | if (neighbourRegion == null) | 1566 | if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) |
1567 | { | ||
1568 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1691 | return agent; | 1569 | return agent; |
1570 | } | ||
1692 | 1571 | ||
1693 | if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) | 1572 | if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) |
1694 | { | 1573 | { |
1695 | m_log.ErrorFormat( | 1574 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); |
1696 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit", | ||
1697 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName); | ||
1698 | return agent; | 1575 | return agent; |
1699 | } | 1576 | } |
1700 | 1577 | ||
1701 | bool transitWasReset = false; | 1578 | CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); |
1579 | return agent; | ||
1580 | } | ||
1702 | 1581 | ||
1582 | public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) | ||
1583 | { | ||
1703 | try | 1584 | try |
1704 | { | 1585 | { |
1705 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 1586 | AgentData cAgent = new AgentData(); |
1706 | |||
1707 | m_log.DebugFormat( | ||
1708 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1709 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
1710 | |||
1711 | Scene m_scene = agent.Scene; | ||
1712 | |||
1713 | if (!agent.ValidateAttachments()) | ||
1714 | m_log.DebugFormat( | ||
1715 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1716 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1717 | |||
1718 | pos = pos + agent.Velocity; | ||
1719 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1720 | |||
1721 | agent.RemoveFromPhysicalScene(); | ||
1722 | |||
1723 | AgentData cAgent = new AgentData(); | ||
1724 | agent.CopyTo(cAgent); | 1587 | agent.CopyTo(cAgent); |
1725 | cAgent.Position = pos; | 1588 | cAgent.Position = pos + agent.Velocity; |
1726 | if (isFlying) | 1589 | if (isFlying) |
1727 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | 1590 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; |
1728 | 1591 | ||
@@ -1732,7 +1595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1732 | // Beyond this point, extra cleanup is needed beyond removing transit state | 1595 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1733 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | 1596 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); |
1734 | 1597 | ||
1735 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1598 | if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) |
1736 | { | 1599 | { |
1737 | // region doesn't take it | 1600 | // region doesn't take it |
1738 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | 1601 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
@@ -1744,88 +1607,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1744 | ReInstantiateScripts(agent); | 1607 | ReInstantiateScripts(agent); |
1745 | agent.AddToPhysicalScene(isFlying); | 1608 | agent.AddToPhysicalScene(isFlying); |
1746 | 1609 | ||
1747 | return agent; | 1610 | return false; |
1748 | } | 1611 | } |
1749 | 1612 | ||
1750 | //m_log.Debug("BEFORE CROSS"); | 1613 | } |
1751 | //Scene.DumpChildrenSeeds(UUID); | 1614 | catch (Exception e) |
1752 | //DumpKnownRegions(); | 1615 | { |
1753 | string agentcaps; | 1616 | m_log.ErrorFormat( |
1754 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | 1617 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", |
1755 | { | 1618 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); |
1756 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | 1619 | |
1757 | neighbourRegion.RegionHandle); | 1620 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. |
1758 | return agent; | 1621 | return false; |
1759 | } | 1622 | } |
1623 | |||
1624 | return true; | ||
1625 | } | ||
1760 | 1626 | ||
1761 | // No turning back | 1627 | public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, |
1762 | agent.IsChildAgent = true; | 1628 | bool isFlying, string version) |
1629 | { | ||
1630 | agent.ControllingClient.RequestClientInfo(); | ||
1763 | 1631 | ||
1764 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1632 | string agentcaps; |
1633 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1634 | { | ||
1635 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1636 | neighbourRegion.RegionHandle); | ||
1637 | return; | ||
1638 | } | ||
1765 | 1639 | ||
1766 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | 1640 | // No turning back |
1641 | agent.IsChildAgent = true; | ||
1767 | 1642 | ||
1768 | if (m_eqModule != null) | 1643 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
1769 | { | ||
1770 | m_eqModule.CrossRegion( | ||
1771 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | ||
1772 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1773 | } | ||
1774 | else | ||
1775 | { | ||
1776 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1777 | capsPath); | ||
1778 | } | ||
1779 | 1644 | ||
1780 | // SUCCESS! | 1645 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); |
1781 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | ||
1782 | 1646 | ||
1783 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | 1647 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); |
1784 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | ||
1785 | 1648 | ||
1786 | agent.MakeChildAgent(); | 1649 | if (m_eqModule != null) |
1650 | { | ||
1651 | m_eqModule.CrossRegion( | ||
1652 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | ||
1653 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1654 | } | ||
1655 | else | ||
1656 | { | ||
1657 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1658 | capsPath); | ||
1659 | } | ||
1787 | 1660 | ||
1788 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | 1661 | // SUCCESS! |
1789 | // but not sure yet what the side effects would be. | 1662 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
1790 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1791 | transitWasReset = true; | ||
1792 | 1663 | ||
1793 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1664 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1794 | agent.SendOtherAgentsAvatarDataToMe(); | 1665 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1795 | agent.SendOtherAgentsAppearanceToMe(); | ||
1796 | 1666 | ||
1797 | // Backwards compatibility. Best effort | 1667 | agent.MakeChildAgent(); |
1798 | if (version == "Unknown" || version == string.Empty) | ||
1799 | { | ||
1800 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1801 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1802 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1803 | } | ||
1804 | 1668 | ||
1805 | // Next, let's close the child agent connections that are too far away. | 1669 | // FIXME: Possibly this should occur lower down after other commands to close other agents, |
1806 | agent.CloseChildAgents(neighbourx, neighboury); | 1670 | // but not sure yet what the side effects would be. |
1671 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1807 | 1672 | ||
1808 | AgentHasMovedAway(agent, false); | 1673 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1809 | 1674 | agent.SendOtherAgentsAvatarDataToMe(); | |
1810 | //m_log.Debug("AFTER CROSS"); | 1675 | agent.SendOtherAgentsAppearanceToMe(); |
1811 | //Scene.DumpChildrenSeeds(UUID); | ||
1812 | //DumpKnownRegions(); | ||
1813 | } | ||
1814 | catch (Exception e) | ||
1815 | { | ||
1816 | m_log.ErrorFormat( | ||
1817 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | ||
1818 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | ||
1819 | 1676 | ||
1820 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | 1677 | // Backwards compatibility. Best effort |
1821 | } | 1678 | if (version == "Unknown" || version == string.Empty) |
1822 | finally | ||
1823 | { | 1679 | { |
1824 | if (!transitWasReset) | 1680 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); |
1825 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | 1681 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback |
1682 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1826 | } | 1683 | } |
1827 | 1684 | ||
1828 | return agent; | 1685 | // Next, let's close the child agent connections that are too far away. |
1686 | uint neighbourx; | ||
1687 | uint neighboury; | ||
1688 | |||
1689 | Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); | ||
1690 | |||
1691 | neighbourx /= Constants.RegionSize; | ||
1692 | neighboury /= Constants.RegionSize; | ||
1693 | |||
1694 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1695 | |||
1696 | AgentHasMovedAway(agent, false); | ||
1697 | |||
1698 | // the user may change their profile information in other region, | ||
1699 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1700 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1701 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1702 | // { | ||
1703 | // m_log.DebugFormat( | ||
1704 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1705 | // } | ||
1706 | |||
1707 | //m_log.Debug("AFTER CROSS"); | ||
1708 | //Scene.DumpChildrenSeeds(UUID); | ||
1709 | //DumpKnownRegions(); | ||
1710 | |||
1711 | return; | ||
1829 | } | 1712 | } |
1830 | 1713 | ||
1831 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1714 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
@@ -1896,10 +1779,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1896 | agent.Id0 = currentAgentCircuit.Id0; | 1779 | agent.Id0 = currentAgentCircuit.Id0; |
1897 | } | 1780 | } |
1898 | 1781 | ||
1899 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | 1782 | IPEndPoint external = region.ExternalEndPoint; |
1900 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | 1783 | if (external != null) |
1784 | { | ||
1785 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
1786 | d.BeginInvoke(sp, agent, region, external, true, | ||
1901 | InformClientOfNeighbourCompleted, | 1787 | InformClientOfNeighbourCompleted, |
1902 | d); | 1788 | d); |
1789 | } | ||
1903 | } | 1790 | } |
1904 | #endregion | 1791 | #endregion |
1905 | 1792 | ||
@@ -2116,7 +2003,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2116 | if (ret == null) | 2003 | if (ret == null) |
2117 | { | 2004 | { |
2118 | // If the simple lookup failed, search the larger area for a region that contains this point | 2005 | // If the simple lookup failed, search the larger area for a region that contains this point |
2119 | double range = (double)Constants.RegionSize + 2; | 2006 | double range = (double)Constants.RegionSize * 2 + 2; |
2120 | while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) | 2007 | while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize)) |
2121 | { | 2008 | { |
2122 | // Get from the grid service a list of regions that might contain this point | 2009 | // Get from the grid service a list of regions that might contain this point |
@@ -2387,175 +2274,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2387 | return; | 2274 | return; |
2388 | } | 2275 | } |
2389 | 2276 | ||
2390 | /* | ||
2391 | int thisx = (int)scene.RegionInfo.LegacyRegionLocX; | ||
2392 | int thisy = (int)scene.RegionInfo.LegacyRegionLocY; | ||
2393 | Vector3 EastCross = new Vector3(0.1f, 0, 0); | ||
2394 | Vector3 WestCross = new Vector3(-0.1f, 0, 0); | ||
2395 | Vector3 NorthCross = new Vector3(0, 0.1f, 0); | ||
2396 | Vector3 SouthCross = new Vector3(0, -0.1f, 0); | ||
2397 | |||
2398 | |||
2399 | // use this default if no borders were crossed (handle of the current region) | ||
2400 | ulong newRegionHandle = Util.RegionWorldLocToHandle(scene.RegionInfo.RegionWorldLocX, scene.RegionInfo.RegionWorldLocY); | ||
2401 | |||
2402 | Vector3 pos = attemptedPosition; | ||
2403 | |||
2404 | int changeX = 1; | ||
2405 | int changeY = 1; | ||
2406 | |||
2407 | if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W)) | ||
2408 | { | ||
2409 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
2410 | { | ||
2411 | |||
2412 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2413 | |||
2414 | if (crossedBorderx.BorderLine.Z > 0) | ||
2415 | { | ||
2416 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
2417 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2418 | } | ||
2419 | else | ||
2420 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2421 | |||
2422 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2423 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2424 | |||
2425 | if (crossedBordery.BorderLine.Z > 0) | ||
2426 | { | ||
2427 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2428 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2429 | } | ||
2430 | else | ||
2431 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2432 | |||
2433 | |||
2434 | |||
2435 | newRegionHandle | ||
2436 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
2437 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2438 | // x - 1 | ||
2439 | // y - 1 | ||
2440 | } | ||
2441 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2442 | { | ||
2443 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2444 | |||
2445 | if (crossedBorderx.BorderLine.Z > 0) | ||
2446 | { | ||
2447 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
2448 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2449 | } | ||
2450 | else | ||
2451 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2452 | |||
2453 | |||
2454 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2455 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2456 | |||
2457 | if (crossedBordery.BorderLine.Z > 0) | ||
2458 | { | ||
2459 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2460 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2461 | } | ||
2462 | else | ||
2463 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2464 | |||
2465 | newRegionHandle | ||
2466 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
2467 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
2468 | // x - 1 | ||
2469 | // y + 1 | ||
2470 | } | ||
2471 | else | ||
2472 | { | ||
2473 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
2474 | |||
2475 | if (crossedBorderx.BorderLine.Z > 0) | ||
2476 | { | ||
2477 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
2478 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
2479 | } | ||
2480 | else | ||
2481 | pos.X = ((pos.X + Constants.RegionSize)); | ||
2482 | |||
2483 | newRegionHandle | ||
2484 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
2485 | (uint)(thisy * Constants.RegionSize)); | ||
2486 | // x - 1 | ||
2487 | } | ||
2488 | } | ||
2489 | else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E)) | ||
2490 | { | ||
2491 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
2492 | { | ||
2493 | |||
2494 | pos.X = ((pos.X - Constants.RegionSize)); | ||
2495 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2496 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2497 | |||
2498 | if (crossedBordery.BorderLine.Z > 0) | ||
2499 | { | ||
2500 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2501 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2502 | } | ||
2503 | else | ||
2504 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2505 | |||
2506 | |||
2507 | newRegionHandle | ||
2508 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2509 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2510 | // x + 1 | ||
2511 | // y - 1 | ||
2512 | } | ||
2513 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2514 | { | ||
2515 | pos.X = ((pos.X - Constants.RegionSize)); | ||
2516 | pos.Y = ((pos.Y - Constants.RegionSize)); | ||
2517 | newRegionHandle | ||
2518 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2519 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
2520 | // x + 1 | ||
2521 | // y + 1 | ||
2522 | } | ||
2523 | else | ||
2524 | { | ||
2525 | pos.X = ((pos.X - Constants.RegionSize)); | ||
2526 | newRegionHandle | ||
2527 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
2528 | (uint)(thisy * Constants.RegionSize)); | ||
2529 | // x + 1 | ||
2530 | } | ||
2531 | } | ||
2532 | else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
2533 | { | ||
2534 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
2535 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
2536 | |||
2537 | if (crossedBordery.BorderLine.Z > 0) | ||
2538 | { | ||
2539 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
2540 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
2541 | } | ||
2542 | else | ||
2543 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
2544 | |||
2545 | newRegionHandle | ||
2546 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize)); | ||
2547 | // y - 1 | ||
2548 | } | ||
2549 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
2550 | { | ||
2551 | |||
2552 | pos.Y = ((pos.Y - Constants.RegionSize)); | ||
2553 | newRegionHandle | ||
2554 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); | ||
2555 | // y + 1 | ||
2556 | } | ||
2557 | */ | ||
2558 | |||
2559 | // Remember the old group position in case the region lookup fails so position can be restored. | 2277 | // Remember the old group position in case the region lookup fails so position can be restored. |
2560 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; | 2278 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; |
2561 | 2279 | ||
@@ -2576,30 +2294,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2576 | attemptedPosition.Z); | 2294 | attemptedPosition.Z); |
2577 | } | 2295 | } |
2578 | 2296 | ||
2579 | if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) | 2297 | if (destination != null) |
2580 | { | 2298 | { |
2581 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); | 2299 | if (!CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) |
2582 | 2300 | { | |
2583 | // We are going to move the object back to the old position so long as the old position | 2301 | m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); |
2584 | // is in the region | 2302 | |
2585 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); | 2303 | // We are going to move the object back to the old position so long as the old position |
2586 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); | 2304 | // is in the region |
2587 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); | 2305 | oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1)); |
2588 | 2306 | oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1)); | |
2589 | grp.RootPart.GroupPosition = oldGroupPosition; | 2307 | oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight); |
2590 | 2308 | ||
2591 | // Need to turn off the physics flags, otherwise the object will continue to attempt to | 2309 | grp.AbsolutePosition = oldGroupPosition; |
2592 | // move out of the region creating an infinite loop of failed attempts to cross | 2310 | grp.Velocity = Vector3.Zero; |
2593 | grp.UpdatePrimFlags(grp.RootPart.LocalId, false, grp.IsTemporary, grp.IsPhantom, false); | 2311 | if (grp.RootPart.PhysActor != null) |
2594 | 2312 | grp.RootPart.PhysActor.CrossingFailure(); | |
2595 | if (grp.RootPart.KeyframeMotion != null) | 2313 | |
2596 | grp.RootPart.KeyframeMotion.CrossingFailure(); | 2314 | if (grp.RootPart.KeyframeMotion != null) |
2597 | 2315 | grp.RootPart.KeyframeMotion.CrossingFailure(); | |
2598 | grp.ScheduleGroupForFullUpdate(); | 2316 | |
2317 | grp.ScheduleGroupForFullUpdate(); | ||
2318 | } | ||
2599 | } | 2319 | } |
2600 | } | 2320 | } |
2601 | 2321 | ||
2602 | |||
2603 | /// <summary> | 2322 | /// <summary> |
2604 | /// Move the given scene object into a new region | 2323 | /// Move the given scene object into a new region |
2605 | /// </summary> | 2324 | /// </summary> |
@@ -2650,17 +2369,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2650 | grp, e); | 2369 | grp, e); |
2651 | } | 2370 | } |
2652 | } | 2371 | } |
2372 | /* | ||
2373 | * done on caller ( not in attachments crossing for now) | ||
2653 | else | 2374 | else |
2654 | { | 2375 | { |
2376 | |||
2655 | if (!grp.IsDeleted) | 2377 | if (!grp.IsDeleted) |
2656 | { | 2378 | { |
2657 | PhysicsActor pa = grp.RootPart.PhysActor; | 2379 | PhysicsActor pa = grp.RootPart.PhysActor; |
2658 | if (pa != null) | 2380 | if (pa != null) |
2381 | { | ||
2659 | pa.CrossingFailure(); | 2382 | pa.CrossingFailure(); |
2383 | if (grp.RootPart.KeyframeMotion != null) | ||
2384 | { | ||
2385 | // moved to KeyframeMotion.CrossingFailure | ||
2386 | // grp.RootPart.Velocity = Vector3.Zero; | ||
2387 | grp.RootPart.KeyframeMotion.CrossingFailure(); | ||
2388 | // grp.SendGroupRootTerseUpdate(); | ||
2389 | } | ||
2390 | } | ||
2660 | } | 2391 | } |
2661 | 2392 | ||
2662 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | 2393 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); |
2663 | } | 2394 | } |
2395 | */ | ||
2664 | } | 2396 | } |
2665 | else | 2397 | else |
2666 | { | 2398 | { |