diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 5a5e5d0413..8b1a98286b 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -816,7 +816,7 @@ namespace OpenSim.Framework event TeleportCancel OnTeleportCancel; event DeRezObject OnDeRezObject; event RezRestoreToWorld OnRezRestoreToWorld; - event Action OnRegionHandShakeReply; + event Action OnRegionHandShakeReply; event GenericCall1 OnRequestWearables; event Action OnCompleteMovementToRegion; @@ -1511,6 +1511,6 @@ namespace OpenSim.Framework void SendAgentTerseUpdate(ISceneEntity presence); void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data); - void CheckViewerCaps(); + uint GetViewerCaps(); } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d21452febd..6859b8357c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event DeRezObject OnDeRezObject; public event RezRestoreToWorld OnRezRestoreToWorld; public event ModifyTerrain OnModifyTerrain; - public event Action OnRegionHandShakeReply; + public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; public event SetAppearance OnSetAppearance; public event AvatarNowWearing OnAvatarNowWearing; @@ -8923,7 +8923,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool HandlerRegionHandshakeReply(IClientAPI sender, Packet Pack) { - Action handlerRegionHandShakeReply = OnRegionHandShakeReply; + Action handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply == null) return true; // silence the warning @@ -8936,7 +8936,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else m_viewerHandShakeFlags = 0; - handlerRegionHandShakeReply(this, m_viewerHandShakeFlags); + handlerRegionHandShakeReply(this); return true; } @@ -15364,15 +15364,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP return new HashSet(m_inPacketsToDrop); } - public void CheckViewerCaps() + public uint GetViewerCaps() { m_SupportObjectAnimations = false; + uint ret; + if(m_supportViewerCache) + ret = m_viewerHandShakeFlags; + else + ret = m_viewerHandShakeFlags & 4; + if (m_scene.CapsModule != null) { Caps cap = m_scene.CapsModule.GetCapsForUser(CircuitCode); - if (cap != null && (cap.Flags & Caps.CapsFlags.ObjectAnim) != 0) - m_SupportObjectAnimations = true; + if(cap != null) + { + if((cap.Flags & Caps.CapsFlags.SentSeeds) != 0) + ret |= 0x1000; + if ((cap.Flags & Caps.CapsFlags.ObjectAnim) != 0) + { + m_SupportObjectAnimations = true; + ret |= 0x2000; + } + } } + return ret; // ??? } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index b105d52c5a..6746573860 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1698,7 +1698,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } // Now we know we can handle more data - Thread.Sleep(200); + //Thread.Sleep(200); // Obtain the pending queue and remove it from the cache Queue queue = null; @@ -1727,7 +1727,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if(aCircuit.teleportFlags <= 0) client.SendRegionHandshake(); - client.CheckViewerCaps(); } } else @@ -1743,8 +1742,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } // m_log.DebugFormat( - // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", - // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); + // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", + // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); } catch (Exception e) @@ -1758,117 +1757,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP e.StackTrace); } } -/* - protected void HandleCompleteMovementIntoRegion(object o) - { - IPEndPoint endPoint = null; - IClientAPI client = null; - - try - { - object[] array = (object[])o; - endPoint = (IPEndPoint)array[0]; - CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1]; - - m_log.DebugFormat( - "[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name); - - // Determine which agent this packet came from - // We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination - // simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode - // and then CompleteAgentMovement immediately without waiting for an ack. As we are now handling these - // packets asynchronously, we need to account for this thread proceeding more quickly than the - // UseCircuitCode thread. - int count = 40; - while (count-- > 0) - { - if (Scene.TryGetClient(endPoint, out client)) - { - if (!client.IsActive) - { - // This check exists to catch a condition where the client has been closed by another thread - // but has not yet been removed from the client manager (and possibly a new connection has - // not yet been established). - m_log.DebugFormat( - "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.", - endPoint, client.Name, Scene.Name); - } - else if (client.SceneAgent == null) - { - // This check exists to catch a condition where the new client has been added to the client - // manager but the SceneAgent has not yet been set in Scene.AddNewAgent(). If we are too - // eager, then the new ScenePresence may not have registered a listener for this messsage - // before we try to process it. - // XXX: A better long term fix may be to add the SceneAgent before the client is added to - // the client manager - m_log.DebugFormat( - "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.", - endPoint, client.Name, Scene.Name); - } - else - { - break; - } - } - else - { - m_log.DebugFormat( - "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.", - endPoint, Scene.Name); - } - - Thread.Sleep(200); - } - - if (client == null) - { - m_log.DebugFormat( - "[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.", - endPoint, Scene.Name); - - return; - } - else if (!client.IsActive || client.SceneAgent == null) - { - // This check exists to catch a condition where the client has been closed by another thread - // but has not yet been removed from the client manager. - // The packet could be simply ignored but it is useful to know if this condition occurred for other debugging - // purposes. - m_log.DebugFormat( - "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.", - endPoint, client.Name, Scene.Name); - - return; - } - - IncomingPacket incomingPacket1; - - // Inbox insertion - if (UsePools) - { - incomingPacket1 = m_incomingPacketPool.GetObject(); - incomingPacket1.Client = (LLClientView)client; - incomingPacket1.Packet = packet; - } - else - { - incomingPacket1 = new IncomingPacket((LLClientView)client, packet); - } - - packetInbox.Enqueue(incomingPacket1); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[LLUDPSERVER]: CompleteAgentMovement handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", - endPoint != null ? endPoint.ToString() : "n/a", - client != null ? client.Name : "unknown", - client != null ? client.AgentId.ToString() : "unknown", - e.Message, - e.StackTrace); - } - } -*/ /// /// Send an ack immediately to the given endpoint. @@ -1936,7 +1824,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (Scene.TryGetClient(agentID, out client)) { - if (client.SceneAgent != null) + if (client.SceneAgent != null && + client.CircuitCode == circuitCode && + client.SessionId == sessionID && + client.RemoteEndPoint == remoteEndPoint && + client.SceneAgent.ControllingClient.SecureSessionId == sessionInfo.LoginInfo.SecureSession) return client; Scene.CloseAgent(agentID, true); } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 26500ab3e7..094b0f523b 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1841,7 +1841,7 @@ namespace OpenSim.Region.CoreModules.World.Land UUID lgid = LandData.GlobalID; m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - if(sp.IsNPC || sp.IsLoggingIn || sp.IsDeleted || sp.currentParcelUUID != lgid) + if(sp.IsNPC || sp.IsDeleted || sp.currentParcelUUID != lgid) return; cur += (now - sp.ParcelDwellTickMS); sp.ParcelDwellTickMS = now; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a95036c198..123b605dc7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -99,6 +99,8 @@ namespace OpenSim.Region.Framework.Scenes public bool IsViewerUIGod { get; set; } public bool IsGod { get; set; } + private bool m_gotRegionHandShake = false; + private PresenceType m_presenceType; public PresenceType PresenceType { @@ -288,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_lastRotation; private Vector3 m_lastVelocity; private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); - private bool SentInitialData = false; + private bool NeedInitialData = false; private int m_userFlags; public int UserFlags @@ -881,7 +883,6 @@ namespace OpenSim.Region.Framework.Scenes } public bool IsChildAgent { get; set; } - public bool IsLoggingIn { get; set; } /// /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. @@ -1074,7 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes AttachmentsSyncLock = new Object(); AllowMovement = true; IsChildAgent = true; - IsLoggingIn = false; m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; Animator = new ScenePresenceAnimator(this); Overrides = new MovementAnimationOverrides(); @@ -1307,7 +1307,6 @@ namespace OpenSim.Region.Framework.Scenes ParentPart = null; PrevSitOffset = Vector3.Zero; HandleForceReleaseControls(ControllingClient, UUID); // needs testing - IsLoggingIn = false; } else { @@ -1331,10 +1330,6 @@ namespace OpenSim.Region.Framework.Scenes } ParentUUID = UUID.Zero; } - else - { - IsLoggingIn = false; - } IsChildAgent = false; } @@ -2163,7 +2158,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); // recheck to reduce timing issues - ControllingClient.CheckViewerCaps(); + ControllingClient.GetViewerCaps(); bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0; @@ -2325,9 +2320,40 @@ namespace OpenSim.Region.Framework.Scenes } } } - if(!IsNPC) + //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + if (!IsNPC) { - //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + if (!string.IsNullOrEmpty(m_callbackURI)) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Releasing {0} {1} with old callback to {2}", + client.Name, client.AgentId, m_callbackURI); + + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); + m_callbackURI = null; + //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + } + else if (!string.IsNullOrEmpty(m_newCallbackURI)) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", + client.Name, client.AgentId, m_newCallbackURI); + + UUID originID; + + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + + Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI); + m_newCallbackURI = null; + //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + } + if (openChildAgents) { // Create child agents in neighbouring regions @@ -2360,36 +2386,6 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - if (!string.IsNullOrEmpty(m_callbackURI)) - { - m_log.DebugFormat( - "[SCENE PRESENCE]: Releasing {0} {1} with old callback to {2}", - client.Name, client.AgentId, m_callbackURI); - - UUID originID; - - lock (m_originRegionIDAccessLock) - originID = m_originRegionID; - - Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); - m_callbackURI = null; - //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - } - else if (!string.IsNullOrEmpty(m_newCallbackURI)) - { - m_log.DebugFormat( - "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", - client.Name, client.AgentId, m_newCallbackURI); - - UUID originID; - - lock (m_originRegionIDAccessLock) - originID = m_originRegionID; - - Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI); - m_newCallbackURI = null; - //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); - } if (openChildAgents) { @@ -3850,15 +3846,21 @@ namespace OpenSim.Region.Framework.Scenes public override void Update() { - if(IsChildAgent || IsDeleted) + if (IsDeleted) + return; + + if (NeedInitialData) + { + SendInitialData(); + return; + } + + if (IsChildAgent || IsInTransit) return; CheckForBorderCrossing(); - if (IsInTransit || IsLoggingIn) - return; - - if(m_movingToTarget) + if (m_movingToTarget) { m_delayedStop = -1; Vector3 control = Vector3.Zero; @@ -4033,25 +4035,28 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); } - public void RegionHandShakeReply (IClientAPI client, uint flags) + public void RegionHandShakeReply (IClientAPI client) { if(IsNPC) return; lock (m_completeMovementLock) { - if (SentInitialData) + if(m_gotRegionHandShake) return; - SentInitialData = true; + NeedInitialData = true; } + } + + private void SendInitialData() + { + uint flags = ControllingClient.GetViewerCaps(); + if((flags & 0x1000) == 0) // wait for seeds sending + return; + + NeedInitialData = false; bool selfappearance = (flags & 4) != 0; - bool cacheCulling = (flags & 1) != 0; - bool cacheEmpty; - if(cacheCulling) - cacheEmpty = (flags & 2) != 0; - else - cacheEmpty = true; Util.FireAndForget(delegate { @@ -4066,9 +4071,6 @@ namespace OpenSim.Region.Framework.Scenes SendOtherAgentsAvatarFullToMe(); } - // recheck to reduce timing issues - ControllingClient.CheckViewerCaps(); - if (m_scene.ObjectsCullingByDistance) { m_reprioritizationBusy = true; @@ -4081,6 +4083,13 @@ namespace OpenSim.Region.Framework.Scenes return; } + bool cacheCulling = (flags & 1) != 0; + bool cacheEmpty; + if (cacheCulling) + cacheEmpty = (flags & 2) != 0; + else + cacheEmpty = true; + EntityBase[] entities = Scene.Entities.GetEntities(); if(cacheEmpty) { @@ -6816,7 +6825,8 @@ namespace OpenSim.Region.Framework.Scenes lock (m_completeMovementLock) { GodController.HasMovedAway(); - SentInitialData = false; + NeedInitialData = false; + m_gotRegionHandShake = false; } List allpresences = m_scene.GetScenePresences(); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 80baf82dbc..9f85185dc0 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -699,7 +699,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event TeleportCancel OnTeleportCancel; public event DeRezObject OnDeRezObject; public event RezRestoreToWorld OnRezRestoreToWorld; - public event Action OnRegionHandShakeReply; + public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; @@ -938,12 +938,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server if (OnRegionHandShakeReply != null) { - OnRegionHandShakeReply(this, 0); + OnRegionHandShakeReply(this); } if (OnCompleteMovementToRegion != null) { - OnCompleteMovementToRegion(this, true); + OnCompleteMovementToRegion(this, false); } } @@ -1773,7 +1773,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server return 0; } - public void CheckViewerCaps() { } + public uint GetViewerCaps() + { + return 0; + } } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index a7ed7d14d5..954d336e04 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -319,7 +319,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event DeRezObject OnDeRezObject; public event RezRestoreToWorld OnRezRestoreToWorld; - public event Action OnRegionHandShakeReply; + public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; @@ -928,7 +928,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { if (OnRegionHandShakeReply != null) { - OnRegionHandShakeReply(this, 0); + OnRegionHandShakeReply(this); } } @@ -1384,7 +1384,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC return 0; } - public void CheckViewerCaps() { } + public uint GetViewerCaps() + { + return 0; + } } } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 4fe2684c9a..0af49f23b4 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -119,7 +119,7 @@ namespace OpenSim.Tests.Common public event DeRezObject OnDeRezObject; public event RezRestoreToWorld OnRezRestoreToWorld; - public event Action OnRegionHandShakeReply; + public event Action OnRegionHandShakeReply; public event GenericCall1 OnRequestWearables; public event Action OnCompleteMovementToRegion; public event UpdateAgent OnPreAgentUpdate; @@ -880,7 +880,7 @@ namespace OpenSim.Tests.Common { if (OnRegionHandShakeReply != null) { - OnRegionHandShakeReply(this, 0); + OnRegionHandShakeReply(this); } } @@ -1398,7 +1398,10 @@ namespace OpenSim.Tests.Common { } - public void CheckViewerCaps() { } + public uint GetViewerCaps() + { + return 0; + } } }