From 355cde464a7ada3c6ab8fce7eb4118ad5cec0351 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 8 Dec 2011 16:10:47 +0000 Subject: Simplify Scene.AddNewClient() If sp becomes null right after we've checked or created it, then behaviour down the line is going to be wrong anyway. So instead retain the check/create ScenePresence reference and use this. --- OpenSim/Region/Framework/Scenes/Scene.cs | 45 ++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 87af206..21c4a87 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2487,7 +2487,7 @@ namespace OpenSim.Region.Framework.Scenes #region Add/Remove Avatar Methods /// - /// Add a new client and create a child agent for it. + /// Add a new client and create a child scene presence for it. /// /// /// The type of agent to add. @@ -2504,42 +2504,53 @@ namespace OpenSim.Region.Framework.Scenes CheckHeartbeat(); - if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here + ScenePresence sp = GetScenePresence(client.AgentId); + + // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this + // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause + // other problems, and possible the code calling AddNewClient() should ensure that no client is already + // connected. + if (sp == null) { - m_log.Debug("[SCENE]: Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName); + m_log.Debug("[SCENE]: Adding new child scene presence " + client.Name + " to scene " + RegionInfo.RegionName); m_clientManager.Add(client); SubscribeToClientEvents(client); - ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); + sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); m_eventManager.TriggerOnNewPresence(sp); sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags; - // HERE!!! Do the initial attachments right here - // first agent upon login is a root agent by design. - // All other AddNewClient calls find aCircuit.child to be true + // The first agent upon login is a root agent by design. + // For this agent we will have to rez the attachments. + // All other AddNewClient calls find aCircuit.child to be true. if (aCircuit.child == false) { + // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to + // start the scripts again (since this is done in RezAttachments()). + // XXX: This is convoluted. sp.IsChildAgent = false; if (AttachmentsModule != null) Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); } } - - ScenePresence createdSp = GetScenePresence(client.AgentId); - if (createdSp != null) + else { - m_LastLogin = Util.EnvironmentTickCount(); + m_log.WarnFormat( + "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", + sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); + } - // Cache the user's name - CacheUserName(createdSp, aCircuit); + m_LastLogin = Util.EnvironmentTickCount(); - EventManager.TriggerOnNewClient(client); - if (vialogin) - EventManager.TriggerOnClientLogin(client); - } + // Cache the user's name + CacheUserName(sp, aCircuit); + + EventManager.TriggerOnNewClient(client); + if (vialogin) + EventManager.TriggerOnClientLogin(client); // Send all scene object to the new client Util.FireAndForget(delegate -- cgit v1.1 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 --- OpenSim/Region/Framework/Scenes/Scene.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 21c4a87..d47536a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2491,13 +2491,13 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// The type of agent to add. - public override void AddNewClient(IClientAPI client, PresenceType type) + public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) { AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); bool vialogin = false; if (aCircuit == null) // no good, didn't pass NewUserConnection successfully - return; + return null; vialogin = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; @@ -2552,16 +2552,7 @@ namespace OpenSim.Region.Framework.Scenes if (vialogin) EventManager.TriggerOnClientLogin(client); - // Send all scene object to the new client - Util.FireAndForget(delegate - { - EntityBase[] entities = Entities.GetEntities(); - foreach(EntityBase e in entities) - { - if (e != null && e is SceneObjectGroup) - ((SceneObjectGroup)e).SendFullUpdateToClient(client); - } - }); + return sp; } /// -- cgit v1.1