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