diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index cc9fcea2e7..1600bdc00d 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -302,31 +302,26 @@ namespace OpenSim.Framework if (args["start_pos"] != null) Vector3.TryParse(args["start_pos"].AsString(), out startpos); -// DEBUG ON - m_log.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); -// DEBUG OFF + m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); try { - // Unpack various appearance elements - Appearance = new AvatarAppearance(AgentID); + // Unpack various appearance elements + Appearance = new AvatarAppearance(AgentID); - // Eventually this code should be deprecated, use full appearance - // packing in packed_appearance - if (args["appearance_serial"] != null) - Appearance.Serial = args["appearance_serial"].AsInteger(); + // Eventually this code should be deprecated, use full appearance + // packing in packed_appearance + if (args["appearance_serial"] != null) + Appearance.Serial = args["appearance_serial"].AsInteger(); - if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map)) - { - Appearance.Unpack((OSDMap)args["packed_appearance"]); -// DEBUG ON - m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); -// DEBUG OFF + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map)) + { + Appearance.Unpack((OSDMap)args["packed_appearance"]); + m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance"); + } + else + m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); } -// DEBUG ON - else - m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); -// DEBUG OFF - } catch (Exception e) + catch (Exception e) { m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message); } diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index a2273385e0..ce0b2fb784 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -331,9 +331,7 @@ namespace OpenSim.Framework public virtual OSDMap Pack() { -// DEBUG ON - m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data"); -// DEBUG OFF + m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); OSDMap args = new OSDMap(); args["message_type"] = OSD.FromString("AgentData"); @@ -454,9 +452,7 @@ namespace OpenSim.Framework /// public virtual void Unpack(OSDMap args) { -// DEBUG ON - m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data"); -// DEBUG OFF + m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); if (args.ContainsKey("region_id")) UUID.TryParse(args["region_id"].AsString(), out RegionID); @@ -613,10 +609,8 @@ namespace OpenSim.Framework if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); -// DEBUG ON else m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); -// DEBUG OFF if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0df4585eec..ab1c206f9a 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory }); } - // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); + m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); } // Process the visual params, this may change height as well @@ -196,12 +196,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory sp.SetHeight(sp.Appearance.AvatarHeight); } } - - // Send the appearance back to the avatar, not clear that this is needed - sp.ControllingClient.SendAvatarDataImmediate(sp); - // AvatarAppearance avp = sp.Appearance; - // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); - } @@ -274,21 +268,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); - // sp.ControllingClient.SendAvatarDataImmediate(sp); - - // Send the appearance back to the avatar - // AvatarAppearance avp = sp.Appearance; - // sp.ControllingClient.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes()); - -/* -// this needs to be fixed, the flag should be on scene presence not the region module - // Start the animations if necessary - if (!m_startAnimationSet) - { - sp.Animator.UpdateMovementAnimations(); - m_startAnimationSet = true; - } -*/ } private void HandleAppearanceSave(UUID agentid) @@ -374,6 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); + // operate on a copy of the appearance so we don't have to lock anything AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) @@ -388,9 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory SetAppearanceAssets(sp.UUID, ref avatAppearance); // could get fancier with the locks here, but in the spirit of "last write wins" - // this should work correctly + // this should work correctly, also, we don't need to send the appearance here + // since the "iswearing" will trigger a new set of visual param and baked texture changes + // when those complete, the new appearance will be sent sp.Appearance = avatAppearance; - m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); + QueueAppearanceSave(client.AgentId); } private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f02a9228e5..b57dc88fdb 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -903,8 +903,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } agent.MakeChildAgent(); + // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendInitialFullUpdateToAllClients(); + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index db69093f83..4a48ac3bb1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -703,7 +703,9 @@ namespace OpenSim.Region.Framework.Scenes // Note: This won't send data *to* other clients in that region (children don't send) // MIC: This gets called again in CompleteMovement - SendInitialFullUpdateToAllClients(); + // SendInitialFullUpdateToAllClients(); + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); RegisterToEvents(); SetDirectionVectors(); @@ -1613,7 +1615,7 @@ namespace OpenSim.Region.Framework.Scenes { AbsolutePosition = part.AbsolutePosition; Velocity = Vector3.Zero; - SendFullUpdateToAllClients(); + SendAvatarDataToAllAgents(); //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); } @@ -1688,7 +1690,7 @@ namespace OpenSim.Region.Framework.Scenes m_parentPosition = Vector3.Zero; m_parentID = 0; - SendFullUpdateToAllClients(); + SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; if (m_physicsActor != null && m_appearance != null) { @@ -2154,7 +2156,7 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); Animator.TrySetMovementAnimation(sitAnimation); - SendFullUpdateToAllClients(); + SendAvatarDataToAllAgents(); // This may seem stupid, but Our Full updates don't send avatar rotation :P // So we're also sending a terse update (which has avatar rotation) // [Update] We do now. @@ -2379,165 +2381,169 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) + /// Do everything required once a client completes its movement into a region and becomes + /// a root agent. /// - /// - public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) - { - // 2 stage check is needed. - if (remoteAvatar == null) - return; - - IClientAPI cl = remoteAvatar.ControllingClient; - if (cl == null) - return; - - if (m_appearance.Texture == null) - return; - -// MT: This is needed for sit. It's legal to send it to oneself, and the name -// of the method is a misnomer -// -// if (LocalId == remoteAvatar.LocalId) -// { -// m_log.WarnFormat("[SCENEPRESENCE]: An agent is attempting to send avatar data to itself; {0}", UUID); -// return; -// } - - if (IsChildAgent) - { - m_log.WarnFormat("[SCENEPRESENCE]: A child agent is attempting to send out avatar data; {0}", UUID); - return; - } - - remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); - m_scene.StatsReporter.AddAgentUpdates(1); - } - - /// - /// Tell *ALL* agents about this agent - /// - public void SendInitialFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - int avUpdates = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - ++avUpdates; - - // Don't update ourselves - if (avatar.LocalId == LocalId) - return; - - // If this is a root agent, then get info about the avatar - if (!IsChildAgent) - { - SendFullUpdateToOtherClient(avatar); - } - - // If the other avatar is a root - if (!avatar.IsChildAgent) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - avatar.Animator.SendAnimPackToClient(ControllingClient); - } - }); - - m_scene.StatsReporter.AddAgentUpdates(avUpdates); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - //Animator.SendAnimPack(); - } - - public void SendFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - // only send update from root agents to other clients; children are only "listening posts" - if (IsChildAgent) - { - m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent"); - return; - } - - int count = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence sp) - { - if (sp.IsChildAgent) - return; - SendFullUpdateToOtherClient(sp); - ++count; - }); - m_scene.StatsReporter.AddAgentUpdates(count); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - Animator.SendAnimPack(); - } - - /// - /// Do everything required once a client completes its movement into a region - /// - public void SendInitialData() + private void SendInitialData() { // Moved this into CompleteMovement to ensure that m_appearance is initialized before // the inventory arrives // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - m_controllingClient.SendAvatarDataImmediate(this); + // This agent just became root. We are going to tell everyone about it. The process of + // getting other avatars information was initiated in the constructor... don't do it + // again here... + SendAvatarDataToAllAgents(); + + // We have an appearance but we may not have the baked textures. Check the asset cache + // to see if all the baked textures are already here. if (m_scene.AvatarFactory != null) { if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) { // m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); - m_controllingClient.SendAppearance( - m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); + SendAppearanceToAgent(this); + + // If the avatars baked textures are all in the cache, then we have a + // complete appearance... send it out, if not, then we'll send it when + // the avatar finishes updating its appearance + SendAppearanceToAllOtherAgents(); } } else { m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); } - - SendInitialFullUpdateToAllClients(); } /// - /// + /// 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. /// - public void SendAppearanceToAllOtherAgents() + public void SendAvatarDataToAllAgents() { -// DEBUG ON -// m_log.WarnFormat("[SCENEPRESENCE]: Send appearance from {0} to all other agents", m_uuid); -// DEBUG OFF + // only send update from root agents to other clients; children are only "listening posts" + if (IsChildAgent) + { + m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); + return; + } + m_perfMonMS = Util.EnvironmentTickCount(); + int count = 0; m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { - if (scenePresence.UUID != UUID) - { - SendAppearanceToOtherAgent(scenePresence); - } + SendAvatarDataToAgent(scenePresence); + count++; }); + m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } /// - /// Send appearance data to an agent that isn't this one. + /// Send avatar data for all other root agents to this agent, this agent + /// can be either a child or root + /// + public void SendOtherAgentsAvatarDataToMe() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + // only send information about root agents + if (scenePresence.IsChildAgent) + return; + + // only send information about other root agents + if (scenePresence.UUID == UUID) + return; + + scenePresence.SendAvatarDataToAgent(this); + count++; + }); + + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Send avatar data to an agent. /// /// - public void SendAppearanceToOtherAgent(ScenePresence avatar) + private void SendAvatarDataToAgent(ScenePresence avatar) { - if (LocalId == avatar.LocalId) +// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); + + avatar.ControllingClient.SendAvatarDataImmediate(this); + Animator.SendAnimPackToClient(avatar.ControllingClient); + } + + /// + /// Send this agent's appearance to all other root and child agents in the scene + /// This agent must be root. + /// + public void SendAppearanceToAllOtherAgents() + { + // only send update from root agents to other clients; children are only "listening posts" + if (IsChildAgent) { - m_log.WarnFormat("[SCENE PRESENCE]: An agent is attempting to send appearance data to itself; {0}", UUID); + m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); return; } + + m_perfMonMS = Util.EnvironmentTickCount(); -// DEBUG ON + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + if (scenePresence.UUID == UUID) + return; + + SendAppearanceToAgent(scenePresence); + count++; + }); + + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Send appearance from all other root agents to this agent. this agent + /// can be either root or child + /// + public void SendOtherAgentsAppearanceToMe() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + // only send information about root agents + if (scenePresence.IsChildAgent) + return; + + // only send information about other root agents + if (scenePresence.UUID == UUID) + return; + + scenePresence.SendAppearanceToAgent(this); + count++; + }); + + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Send appearance data to an agent. + /// + /// + private void SendAppearanceToAgent(ScenePresence avatar) + { // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); -// DEBUG OFF avatar.ControllingClient.SendAppearance( m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); @@ -3050,9 +3056,6 @@ namespace OpenSim.Region.Framework.Scenes public void CopyFrom(AgentData cAgent) { -// DEBUG ON - m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM"); -// DEBUG OFF m_originRegionID = cAgent.RegionID; m_callbackURI = cAgent.CallbackURI; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 0c8113e604..ccf52892dc 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1173,10 +1173,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups presence = scene.GetScenePresence(AgentID); if (presence != null) { - presence.Grouptitle = Title; + if (presence.Grouptitle != Title) + { + presence.Grouptitle = Title; - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); + if (! presence.IsChildAgent) + presence.SendAvatarDataToAllAgents(); + } } } }