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')
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 ++-------
OpenSim/Region/Framework/Scenes/SceneBase.cs | 2 +-
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 39 +++++++++++++++---------
3 files changed, 29 insertions(+), 27 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
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;
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index a633c72..da15491 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes
#region Add/Remove Agent/Avatar
- public abstract void AddNewClient(IClientAPI client, PresenceType type);
+ public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
public bool TryGetScenePresence(UUID agentID, out object scenePresence)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5b9438b..8e55996 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -782,15 +782,6 @@ namespace OpenSim.Region.Framework.Scenes
AdjustKnownSeeds();
- // we created a new ScenePresence (a new child agent) in a fresh region.
- // Request info about all the (root) agents in this region
- // Note: This won't send data *to* other clients in that region (children don't send)
-
-// MIC: This gets called again in CompleteMovement
- // SendInitialFullUpdateToAllClients();
- SendOtherAgentsAvatarDataToMe();
- SendOtherAgentsAppearanceToMe();
-
RegisterToEvents();
SetDirectionVectors();
@@ -1191,9 +1182,9 @@ namespace OpenSim.Region.Framework.Scenes
{
// DateTime startTime = DateTime.Now;
- m_log.DebugFormat(
- "[SCENE PRESENCE]: Completing movement of {0} into region {1}",
- client.Name, Scene.RegionInfo.RegionName);
+// m_log.DebugFormat(
+// "[SCENE PRESENCE]: Completing movement of {0} into region {1}",
+// client.Name, Scene.RegionInfo.RegionName);
Vector3 look = Velocity;
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1225,7 +1216,7 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
- SendInitialData();
+ ValidateAndSendAppearanceAndAgentData();
// Create child agents in neighbouring regions
if (openChildAgents && !IsChildAgent)
@@ -2512,11 +2503,31 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
}
+ public void SendInitialDataToMe()
+ {
+ // we created a new ScenePresence (a new child agent) in a fresh region.
+ // Request info about all the (root) agents in this region
+ // Note: This won't send data *to* other clients in that region (children don't send)
+ SendOtherAgentsAvatarDataToMe();
+ SendOtherAgentsAppearanceToMe();
+
+ // Send all scene object to the new client
+ Util.FireAndForget(delegate
+ {
+ EntityBase[] entities = Scene.Entities.GetEntities();
+ foreach(EntityBase e in entities)
+ {
+ if (e != null && e is SceneObjectGroup)
+ ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
+ }
+ });
+ }
+
///
/// Do everything required once a client completes its movement into a region and becomes
/// a root agent.
///
- private void SendInitialData()
+ private void ValidateAndSendAppearanceAndAgentData()
{
//m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID);
// Moved this into CompleteMovement to ensure that Appearance is initialized before
--
cgit v1.1
From 54360dd20ef4034e33bfeadcb067d8ff6cbf7e70 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 8 Dec 2011 18:39:56 +0000
Subject: When a client connects to a scene, send other avatar appearance data
asynchronously to reduce hold up in the IN UDP packet processing loop.
This is already being done for the initial object data send.
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 8e55996..a70c276 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2505,15 +2505,15 @@ namespace OpenSim.Region.Framework.Scenes
public void SendInitialDataToMe()
{
- // we created a new ScenePresence (a new child agent) in a fresh region.
- // Request info about all the (root) agents in this region
- // Note: This won't send data *to* other clients in that region (children don't send)
- SendOtherAgentsAvatarDataToMe();
- SendOtherAgentsAppearanceToMe();
-
// Send all scene object to the new client
Util.FireAndForget(delegate
{
+ // we created a new ScenePresence (a new child agent) in a fresh region.
+ // Request info about all the (root) agents in this region
+ // Note: This won't send data *to* other clients in that region (children don't send)
+ SendOtherAgentsAvatarDataToMe();
+ SendOtherAgentsAppearanceToMe();
+
EntityBase[] entities = Scene.Entities.GetEntities();
foreach(EntityBase e in entities)
{
--
cgit v1.1