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
This commit is contained in:
Justin Clark-Casey (justincc)
2011-12-08 18:34:23 +00:00
parent 355cde464a
commit f61e54892f
13 changed files with 171 additions and 78 deletions

View File

@@ -38,28 +38,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// <remarks>
/// Interface is a work in progress. Please feel free to add other required properties and methods.
/// </remarks>
public interface IScenePresence : ISceneEntity
public interface IScenePresence : ISceneAgent
{
/// <value>
/// The client controlling this presence
/// </value>
IClientAPI ControllingClient { get; }
/// <summary>
/// What type of presence is this? User, NPC, etc.
/// </summary>
PresenceType PresenceType { get; }
/// <summary>
/// Avatar appearance data.
/// </summary>
/// <remarks>
// Because appearance setting is in a module, we actually need
// to give it access to our appearance directly, otherwise we
// get a synchronization issue.
/// </remarks>
AvatarAppearance Appearance { get; set; }
/// <summary>
/// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
/// </summary>

View File

@@ -2491,13 +2491,13 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
/// <param name="client"></param>
/// <param name="type">The type of agent to add.</param>
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;
}
/// <summary>

View File

@@ -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)

View File

@@ -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);
}
});
}
/// <summary>
/// Do everything required once a client completes its movement into a region and becomes
/// a root agent.
/// </summary>
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