From f61e54892f2284b6f89bacf3069467c05b2eea11 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 8 Dec 2011 18:34:23 +0000 Subject: On a new client circuit, send the initial reply ack to let the client know it's live before sending other data. This means that avatar/appearance data of other avatars and scene objects for a client will be sent after the ack rather than possibly before. This may stop some avatars appearing grey on login. This introduces a new OpenSim.Framework.ISceneAgent to accompany the existing OpenSim.Framework.ISceneObject and ISceneEntity This allows IClientAPI to handle this as it can't reference OpenSim.Region.Framework.Interfaces --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 4 +- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 58 +++++++++++++++------- .../ClientStack/Linden/UDP/Tests/MockScene.cs | 5 +- 3 files changed, 46 insertions(+), 21 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7d39ddc..f246637 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -379,6 +379,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP set { m_startpos = value; } } public UUID AgentId { get { return m_agentId; } } + public ISceneAgent SceneAgent { get; private set; } public UUID ActiveGroupId { get { return m_activeGroupID; } } public string ActiveGroupName { get { return m_activeGroupName; } } public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } @@ -508,6 +509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Remove ourselves from the scene m_scene.RemoveClient(AgentId, true); + SceneAgent = null; // We can't reach into other scenes and close the connection // We need to do this over grid communications @@ -687,7 +689,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - m_scene.AddNewClient(this, PresenceType.User); + SceneAgent = m_scene.AddNewClient(this, PresenceType.User); RefreshGroupMembership(); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ccad241..7db5f6b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -894,11 +894,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; // Begin the process of adding the client to the simulator - AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); + IClientAPI client = AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); - // Send ack + // Send ack straight away to let the viewer know that the connection is active. SendAckImmediate(remoteEndPoint, packet.Header.Sequence); + // FIXME: Nasty - this is the only way we currently know if Scene.AddNewClient() failed to find a + // circuit and bombed out early. That check might be pointless since authorization is established + // up here. + if (client != null && client.SceneAgent != null) + client.SceneAgent.SendInitialDataToMe(); + // m_log.DebugFormat( // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); @@ -933,7 +939,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP return sessionInfo.Authorised; } - private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint) + /// + /// Add a new client. + /// + /// + /// + /// + /// The client that was added or null if the client failed authorization or already existed. + /// + private IClientAPI AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint) { UUID agentID = useCircuitCode.CircuitCode.ID; UUID sessionID = useCircuitCode.CircuitCode.SessionID; @@ -942,7 +956,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AuthenticateResponse sessionInfo; if (IsClientAuthorized(useCircuitCode, out sessionInfo)) { - AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo); + return AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo); } else { @@ -950,38 +964,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.WarnFormat( "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}", useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint); + + return null; } } - protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) + /// + /// Add a client. + /// + /// + /// + /// + /// + /// + /// The client if it was added. Null if the client already existed. + protected virtual IClientAPI AddClient( + uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) { + IClientAPI client = null; + // In priciple there shouldn't be more than one thread here, ever. // But in case that happens, we need to synchronize this piece of code // because it's too important lock (this) { - IClientAPI existingClient; - - if (!m_scene.TryGetClient(agentID, out existingClient)) + if (!m_scene.TryGetClient(agentID, out client)) { - // Create the LLUDPClient LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); - // Create the LLClientView - LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); + + client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); client.OnLogout += LogoutHandler; - client.DisableFacelights = m_disableFacelights; + ((LLClientView)client).DisableFacelights = m_disableFacelights; - // Start the IClientAPI client.Start(); - - } - else - { - m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", - existingClient.AgentId, remoteEndPoint, circuitCode); } } + + return client; } private void RemoveClient(LLUDPClient udpClient) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs index 737c654..fb94355 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs @@ -53,9 +53,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests public override void Update() {} public override void LoadWorldMap() {} - public override void AddNewClient(IClientAPI client, PresenceType type) + public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) { client.OnObjectName += RecordObjectNameCall; + + // FIXME + return null; } public override void RemoveClient(UUID agentID, bool someReason) {} -- cgit v1.1