Fixed: when teleporting between grids, the avatar name wasn't always updated.

When an avatar is in their home grid, their name appears as "First Last". In other grids the name appears as "First.Last @grid.example.com". However, viewers have a bug and they don't always show the new name. We use a trick (changing the Group Title briefly) in order to make the viewers show the new name. This is only done after a Hypergrid teleport.
0.8.0.3
Oren Hurvitz 2014-04-09 17:00:02 +03:00
parent 06e0528d0b
commit c725ad1577
1 changed files with 67 additions and 6 deletions

View File

@ -451,7 +451,19 @@ namespace OpenSim.Region.Framework.Scenes
public string Firstname { get; private set; }
public string Lastname { get; private set; }
public string Grouptitle { get; set; }
public string Grouptitle
{
get { return UseFakeGroupTitle ? "(Loading)" : m_groupTitle; }
set { m_groupTitle = value; }
}
private string m_groupTitle;
/// <summary>
/// When this is 'true', return a dummy group title instead of the real group title. This is
/// used as part of a hack to force viewers to update the displayed avatar name.
/// </summary>
public bool UseFakeGroupTitle { get; set; }
// Agent's Draw distance.
public float DrawDistance { get; set; }
@ -1051,6 +1063,17 @@ namespace OpenSim.Region.Framework.Scenes
if (gm != null)
Grouptitle = gm.GetGroupTitle(m_uuid);
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode);
uint teleportFlags = (aCircuit == null) ? 0 : aCircuit.teleportFlags;
if ((teleportFlags & (uint)TeleportFlags.ViaHGLogin) != 0)
{
// The avatar is arriving from another grid. This means that we may have changed the
// avatar's name to or from the special Hypergrid format ("First.Last @grid.example.com").
// Unfortunately, due to a viewer bug, viewers don't always show the new name.
// But we have a trick that can force them to update the name anyway.
ForceViewersUpdateName();
}
RegionHandle = m_scene.RegionInfo.RegionHandle;
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
@ -1247,6 +1270,36 @@ namespace OpenSim.Region.Framework.Scenes
return true;
}
/// <summary>
/// Force viewers to show the avatar's current name.
/// </summary>
/// <remarks>
/// The avatar name that is shown above the avatar in the viewers is sent in ObjectUpdate packets,
/// and they get the name from the ScenePresence. Unfortunately, viewers have a bug (as of April 2014)
/// where they ignore changes to the avatar name. However, tey don't ignore changes to the avatar's
/// Group Title. So the following trick makes viewers update the avatar's name by briefly changing
/// the group title (to "(Loading)"), and then restoring it.
/// </remarks>
public void ForceViewersUpdateName()
{
m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name);
UseFakeGroupTitle = true;
SendAvatarDataToAllAgents(false);
Util.FireAndForget(o =>
{
// Viewers only update the avatar name when idle. Therefore, we must wait long
// enough for the viewer to show the fake name that we had set above, and only
// then switch back to the true name. This delay was chosen because it has a high
// chance of succeeding (we don't want to choose a value that's too low).
Thread.Sleep(5000);
UseFakeGroupTitle = false;
SendAvatarDataToAllAgents(false);
});
}
public int GetStateSource()
{
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
@ -3263,11 +3316,16 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void SendAvatarDataToAllAgents()
{
SendAvatarDataToAllAgents(true);
}
/// <summary>
/// Send this agent's avatar data to all other root and child agents in the scene
/// This agent must be root. This avatar will receive its own update.
/// </summary>
public void SendAvatarDataToAllAgents()
public void SendAvatarDataToAllAgents(bool full)
{
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
// only send update from root agents to other clients; children are only "listening posts"
@ -3285,7 +3343,10 @@ namespace OpenSim.Region.Framework.Scenes
int count = 0;
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
{
if (full)
SendAvatarDataToAgent(scenePresence);
else
scenePresence.ControllingClient.SendAvatarDataImmediate(this);
count++;
});