diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 173 |
1 files changed, 91 insertions, 82 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8e6e8fd..07564ba 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1646,109 +1646,118 @@ namespace OpenSim.Region.Framework.Scenes | |||
1646 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", | 1646 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", |
1647 | client.Name, Scene.Name, AbsolutePosition); | 1647 | client.Name, Scene.Name, AbsolutePosition); |
1648 | 1648 | ||
1649 | // Make sure it's not a login agent. We don't want to wait for updates during login | 1649 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1650 | if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) | 1650 | |
1651 | IsInTransit = true; | ||
1652 | try | ||
1651 | { | 1653 | { |
1652 | // Let's wait until UpdateAgent (called by departing region) is done | 1654 | // Make sure it's not a login agent. We don't want to wait for updates during login |
1653 | if (!WaitForUpdateAgent(client)) | 1655 | if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) |
1654 | // The sending region never sent the UpdateAgent data, we have to refuse | 1656 | { |
1655 | return; | 1657 | // Let's wait until UpdateAgent (called by departing region) is done |
1656 | } | 1658 | if (!WaitForUpdateAgent(client)) |
1659 | // The sending region never sent the UpdateAgent data, we have to refuse | ||
1660 | return; | ||
1661 | } | ||
1657 | 1662 | ||
1658 | Vector3 look = Velocity; | 1663 | Vector3 look = Velocity; |
1659 | 1664 | ||
1660 | // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1665 | // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
1661 | if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1)) | 1666 | if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1)) |
1662 | { | 1667 | { |
1663 | look = new Vector3(0.99f, 0.042f, 0); | 1668 | look = new Vector3(0.99f, 0.042f, 0); |
1664 | } | 1669 | } |
1665 | 1670 | ||
1666 | // Prevent teleporting to an underground location | 1671 | // Prevent teleporting to an underground location |
1667 | // (may crash client otherwise) | 1672 | // (may crash client otherwise) |
1668 | // | 1673 | // |
1669 | Vector3 pos = AbsolutePosition; | 1674 | Vector3 pos = AbsolutePosition; |
1670 | float ground = m_scene.GetGroundHeight(pos.X, pos.Y); | 1675 | float ground = m_scene.GetGroundHeight(pos.X, pos.Y); |
1671 | if (pos.Z < ground + 1.5f) | 1676 | if (pos.Z < ground + 1.5f) |
1672 | { | 1677 | { |
1673 | pos.Z = ground + 1.5f; | 1678 | pos.Z = ground + 1.5f; |
1674 | AbsolutePosition = pos; | 1679 | AbsolutePosition = pos; |
1675 | } | 1680 | } |
1676 | 1681 | ||
1677 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | ||
1678 | if (!MakeRootAgent(AbsolutePosition, flying)) | ||
1679 | { | ||
1680 | m_log.DebugFormat( | ||
1681 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1682 | Name, Scene.Name); | ||
1683 | 1682 | ||
1684 | return; | 1683 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1685 | } | 1684 | { |
1685 | m_log.DebugFormat( | ||
1686 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1687 | Name, Scene.Name); | ||
1686 | 1688 | ||
1687 | // Tell the client that we're totally ready | 1689 | return; |
1688 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1690 | } |
1689 | 1691 | ||
1690 | // Remember in HandleUseCircuitCode, we delayed this to here | 1692 | // Tell the client that we're totally ready |
1691 | if (m_teleportFlags > 0) | 1693 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
1692 | SendInitialDataToMe(); | ||
1693 | 1694 | ||
1694 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); | 1695 | // Remember in HandleUseCircuitCode, we delayed this to here |
1696 | if (m_teleportFlags > 0) | ||
1697 | SendInitialDataToMe(); | ||
1695 | 1698 | ||
1696 | if (!string.IsNullOrEmpty(m_callbackURI)) | 1699 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); |
1697 | { | ||
1698 | // We cannot sleep here since this would hold up the inbound packet processing thread, as | ||
1699 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | ||
1700 | // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete | ||
1701 | // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this | ||
1702 | // region as the current region, meaning that a close sent before then will fail the teleport. | ||
1703 | // System.Threading.Thread.Sleep(2000); | ||
1704 | 1700 | ||
1705 | m_log.DebugFormat( | 1701 | if (!string.IsNullOrEmpty(m_callbackURI)) |
1706 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | 1702 | { |
1707 | client.Name, client.AgentId, m_callbackURI); | 1703 | // We cannot sleep here since this would hold up the inbound packet processing thread, as |
1704 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | ||
1705 | // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete | ||
1706 | // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this | ||
1707 | // region as the current region, meaning that a close sent before then will fail the teleport. | ||
1708 | // System.Threading.Thread.Sleep(2000); | ||
1708 | 1709 | ||
1709 | UUID originID; | 1710 | m_log.DebugFormat( |
1711 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | ||
1712 | client.Name, client.AgentId, m_callbackURI); | ||
1710 | 1713 | ||
1711 | lock (m_originRegionIDAccessLock) | 1714 | UUID originID; |
1712 | originID = m_originRegionID; | ||
1713 | 1715 | ||
1714 | Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); | 1716 | lock (m_originRegionIDAccessLock) |
1715 | m_callbackURI = null; | 1717 | originID = m_originRegionID; |
1716 | } | ||
1717 | // else | ||
1718 | // { | ||
1719 | // m_log.DebugFormat( | ||
1720 | // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", | ||
1721 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | ||
1722 | // } | ||
1723 | 1718 | ||
1724 | ValidateAndSendAppearanceAndAgentData(); | 1719 | Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); |
1720 | m_callbackURI = null; | ||
1721 | } | ||
1722 | // else | ||
1723 | // { | ||
1724 | // m_log.DebugFormat( | ||
1725 | // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", | ||
1726 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | ||
1727 | // } | ||
1725 | 1728 | ||
1726 | // Create child agents in neighbouring regions | 1729 | ValidateAndSendAppearanceAndAgentData(); |
1727 | if (openChildAgents && !IsChildAgent) | ||
1728 | { | ||
1729 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
1730 | if (m_agentTransfer != null) | ||
1731 | m_agentTransfer.EnableChildAgents(this); | ||
1732 | 1730 | ||
1733 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); | 1731 | // Create child agents in neighbouring regions |
1734 | if (friendsModule != null) | 1732 | if (openChildAgents && !IsChildAgent) |
1735 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | 1733 | { |
1734 | IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
1735 | if (m_agentTransfer != null) | ||
1736 | m_agentTransfer.EnableChildAgents(this); | ||
1736 | 1737 | ||
1737 | } | 1738 | IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); |
1739 | if (friendsModule != null) | ||
1740 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | ||
1738 | 1741 | ||
1739 | // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region | 1742 | } |
1740 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. | ||
1741 | // This may be due to viewer code or it may be something we're not doing properly simulator side. | ||
1742 | lock (m_attachments) | ||
1743 | { | ||
1744 | foreach (SceneObjectGroup sog in m_attachments) | ||
1745 | sog.ScheduleGroupForFullUpdate(); | ||
1746 | } | ||
1747 | 1743 | ||
1748 | // m_log.DebugFormat( | 1744 | // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region |
1749 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1745 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. |
1750 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | 1746 | // This may be due to viewer code or it may be something we're not doing properly simulator side. |
1747 | lock (m_attachments) | ||
1748 | { | ||
1749 | foreach (SceneObjectGroup sog in m_attachments) | ||
1750 | sog.ScheduleGroupForFullUpdate(); | ||
1751 | } | ||
1751 | 1752 | ||
1753 | // m_log.DebugFormat( | ||
1754 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | ||
1755 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | ||
1756 | } | ||
1757 | finally | ||
1758 | { | ||
1759 | IsInTransit = false; | ||
1760 | } | ||
1752 | } | 1761 | } |
1753 | 1762 | ||
1754 | /// <summary> | 1763 | /// <summary> |