Moved HaveNeighbor utility function from ScenePresence to Scene. Fixed line endings from previous commit.
							parent
							
								
									8b20faf06c
								
							
						
					
					
						commit
						eac29396d9
					
				| 
						 | 
				
			
			@ -105,143 +105,143 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
            client.OnAvatarNowWearing += Client_OnAvatarNowWearing;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region IAvatarFactoryModule
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set appearance data (texture asset IDs and slider settings) 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="sp"></param>
 | 
			
		||||
        /// <param name="texture"></param>
 | 
			
		||||
        /// <param name="visualParam"></param>
 | 
			
		||||
        public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
 | 
			
		||||
        {
 | 
			
		||||
            //            m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
 | 
			
		||||
 | 
			
		||||
            // TODO: This is probably not necessary any longer, just assume the
 | 
			
		||||
            // textureEntry set implies that the appearance transaction is complete
 | 
			
		||||
            bool changed = false;
 | 
			
		||||
 | 
			
		||||
            // Process the texture entry transactionally, this doesn't guarantee that Appearance is
 | 
			
		||||
            // going to be handled correctly but it does serialize the updates to the appearance
 | 
			
		||||
            lock (m_setAppearanceLock)
 | 
			
		||||
            {
 | 
			
		||||
                // Process the visual params, this may change height as well
 | 
			
		||||
                if (visualParams != null)
 | 
			
		||||
                {
 | 
			
		||||
                    //                    string[] visualParamsStrings = new string[visualParams.Length];
 | 
			
		||||
                    //                    for (int i = 0; i < visualParams.Length; i++)
 | 
			
		||||
                    //                        visualParamsStrings[i] = visualParams[i].ToString();
 | 
			
		||||
                    //                    m_log.DebugFormat(
 | 
			
		||||
                    //                        "[AVFACTORY]: Setting visual params for {0} to {1}",
 | 
			
		||||
                    //                        client.Name, string.Join(", ", visualParamsStrings));
 | 
			
		||||
 | 
			
		||||
                    float oldHeight = sp.Appearance.AvatarHeight;
 | 
			
		||||
                    changed = sp.Appearance.SetVisualParams(visualParams);
 | 
			
		||||
 | 
			
		||||
                    if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
 | 
			
		||||
                        ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Process the baked texture array
 | 
			
		||||
                if (textureEntry != null)
 | 
			
		||||
                {
 | 
			
		||||
                    changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
 | 
			
		||||
 | 
			
		||||
                    m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID);
 | 
			
		||||
                    Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(sp, false); });
 | 
			
		||||
 | 
			
		||||
                    // This appears to be set only in the final stage of the appearance
 | 
			
		||||
                    // update transaction. In theory, we should be able to do an immediate
 | 
			
		||||
                    // appearance send and save here.
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                // save only if there were changes, send no matter what (doesn't hurt to send twice)
 | 
			
		||||
                if (changed)
 | 
			
		||||
                    QueueAppearanceSave(sp.ControllingClient.AgentId);
 | 
			
		||||
 | 
			
		||||
                QueueAppearanceSend(sp.ControllingClient.AgentId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SendAppearance(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Send the appearance to everyone in the scene
 | 
			
		||||
            sp.SendAppearanceToAllOtherAgents();
 | 
			
		||||
 | 
			
		||||
            // Send animations back to the avatar as well
 | 
			
		||||
            sp.Animator.SendAnimPack();
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
                return new Dictionary<BakeType, Primitive.TextureEntryFace>();
 | 
			
		||||
 | 
			
		||||
            return GetBakedTextureFaces(sp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SaveBakedTextures(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
 | 
			
		||||
                sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
 | 
			
		||||
            Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
 | 
			
		||||
 | 
			
		||||
            if (bakedTextures.Count == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            foreach (BakeType bakeType in bakedTextures.Keys)
 | 
			
		||||
            {
 | 
			
		||||
                Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
 | 
			
		||||
 | 
			
		||||
                if (bakedTextureFace == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat(
 | 
			
		||||
                        "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
 | 
			
		||||
                        bakeType, sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
 | 
			
		||||
 | 
			
		||||
                if (asset != null)
 | 
			
		||||
                {
 | 
			
		||||
                    asset.Temporary = false;
 | 
			
		||||
                    asset.Local = false;
 | 
			
		||||
                    m_scene.AssetService.Store(asset);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat(
 | 
			
		||||
                        "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
 | 
			
		||||
                        bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region IAvatarFactoryModule
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set appearance data (texture asset IDs and slider settings) 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="sp"></param>
 | 
			
		||||
        /// <param name="texture"></param>
 | 
			
		||||
        /// <param name="visualParam"></param>
 | 
			
		||||
        public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
 | 
			
		||||
        {
 | 
			
		||||
            //            m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
 | 
			
		||||
 | 
			
		||||
            // TODO: This is probably not necessary any longer, just assume the
 | 
			
		||||
            // textureEntry set implies that the appearance transaction is complete
 | 
			
		||||
            bool changed = false;
 | 
			
		||||
 | 
			
		||||
            // Process the texture entry transactionally, this doesn't guarantee that Appearance is
 | 
			
		||||
            // going to be handled correctly but it does serialize the updates to the appearance
 | 
			
		||||
            lock (m_setAppearanceLock)
 | 
			
		||||
            {
 | 
			
		||||
                // Process the visual params, this may change height as well
 | 
			
		||||
                if (visualParams != null)
 | 
			
		||||
                {
 | 
			
		||||
                    //                    string[] visualParamsStrings = new string[visualParams.Length];
 | 
			
		||||
                    //                    for (int i = 0; i < visualParams.Length; i++)
 | 
			
		||||
                    //                        visualParamsStrings[i] = visualParams[i].ToString();
 | 
			
		||||
                    //                    m_log.DebugFormat(
 | 
			
		||||
                    //                        "[AVFACTORY]: Setting visual params for {0} to {1}",
 | 
			
		||||
                    //                        client.Name, string.Join(", ", visualParamsStrings));
 | 
			
		||||
 | 
			
		||||
                    float oldHeight = sp.Appearance.AvatarHeight;
 | 
			
		||||
                    changed = sp.Appearance.SetVisualParams(visualParams);
 | 
			
		||||
 | 
			
		||||
                    if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
 | 
			
		||||
                        ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Process the baked texture array
 | 
			
		||||
                if (textureEntry != null)
 | 
			
		||||
                {
 | 
			
		||||
                    changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
 | 
			
		||||
 | 
			
		||||
                    m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID);
 | 
			
		||||
                    Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(sp, false); });
 | 
			
		||||
 | 
			
		||||
                    // This appears to be set only in the final stage of the appearance
 | 
			
		||||
                    // update transaction. In theory, we should be able to do an immediate
 | 
			
		||||
                    // appearance send and save here.
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                // save only if there were changes, send no matter what (doesn't hurt to send twice)
 | 
			
		||||
                if (changed)
 | 
			
		||||
                    QueueAppearanceSave(sp.ControllingClient.AgentId);
 | 
			
		||||
 | 
			
		||||
                QueueAppearanceSend(sp.ControllingClient.AgentId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SendAppearance(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Send the appearance to everyone in the scene
 | 
			
		||||
            sp.SendAppearanceToAllOtherAgents();
 | 
			
		||||
 | 
			
		||||
            // Send animations back to the avatar as well
 | 
			
		||||
            sp.Animator.SendAnimPack();
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
                return new Dictionary<BakeType, Primitive.TextureEntryFace>();
 | 
			
		||||
 | 
			
		||||
            return GetBakedTextureFaces(sp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SaveBakedTextures(UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentId);
 | 
			
		||||
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
 | 
			
		||||
                sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
 | 
			
		||||
            Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
 | 
			
		||||
 | 
			
		||||
            if (bakedTextures.Count == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            foreach (BakeType bakeType in bakedTextures.Keys)
 | 
			
		||||
            {
 | 
			
		||||
                Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
 | 
			
		||||
 | 
			
		||||
                if (bakedTextureFace == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat(
 | 
			
		||||
                        "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
 | 
			
		||||
                        bakeType, sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
 | 
			
		||||
 | 
			
		||||
                if (asset != null)
 | 
			
		||||
                {
 | 
			
		||||
                    asset.Temporary = false;
 | 
			
		||||
                    asset.Local = false;
 | 
			
		||||
                    m_scene.AssetService.Store(asset);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat(
 | 
			
		||||
                        "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
 | 
			
		||||
                        bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Check for the existence of the baked texture assets.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -249,42 +249,42 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
        public bool ValidateBakedTextureCache(IScenePresence sp)
 | 
			
		||||
        {
 | 
			
		||||
            return ValidateBakedTextureCache(sp, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queue up a request to send appearance, makes it possible to
 | 
			
		||||
        /// accumulate changes without sending out each one separately.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void QueueAppearanceSend(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
 | 
			
		||||
 | 
			
		||||
            // 10000 ticks per millisecond, 1000 milliseconds per second
 | 
			
		||||
            long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
 | 
			
		||||
            lock (m_sendqueue)
 | 
			
		||||
            {
 | 
			
		||||
                m_sendqueue[agentid] = timestamp;
 | 
			
		||||
                m_updateTimer.Start();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void QueueAppearanceSave(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
 | 
			
		||||
 | 
			
		||||
            // 10000 ticks per millisecond, 1000 milliseconds per second
 | 
			
		||||
            long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
 | 
			
		||||
            lock (m_savequeue)
 | 
			
		||||
            {
 | 
			
		||||
                m_savequeue[agentid] = timestamp;
 | 
			
		||||
                m_updateTimer.Start();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region AvatarFactoryModule private methods
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queue up a request to send appearance, makes it possible to
 | 
			
		||||
        /// accumulate changes without sending out each one separately.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void QueueAppearanceSend(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
 | 
			
		||||
 | 
			
		||||
            // 10000 ticks per millisecond, 1000 milliseconds per second
 | 
			
		||||
            long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
 | 
			
		||||
            lock (m_sendqueue)
 | 
			
		||||
            {
 | 
			
		||||
                m_sendqueue[agentid] = timestamp;
 | 
			
		||||
                m_updateTimer.Start();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void QueueAppearanceSave(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
 | 
			
		||||
 | 
			
		||||
            // 10000 ticks per millisecond, 1000 milliseconds per second
 | 
			
		||||
            long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
 | 
			
		||||
            lock (m_savequeue)
 | 
			
		||||
            {
 | 
			
		||||
                m_savequeue[agentid] = timestamp;
 | 
			
		||||
                m_updateTimer.Start();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region AvatarFactoryModule private methods
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Check for the existence of the baked texture assets. Request a rebake
 | 
			
		||||
        /// unless checkonly is true.
 | 
			
		||||
| 
						 | 
				
			
			@ -416,105 +416,105 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
 | 
			
		||||
            if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
 | 
			
		||||
                m_updateTimer.Stop();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveAppearance(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
 | 
			
		||||
            // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
 | 
			
		||||
            // number seperators.
 | 
			
		||||
            Culture.SetCurrentCulture();
 | 
			
		||||
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentid);
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
 | 
			
		||||
 | 
			
		||||
            // This could take awhile since it needs to pull inventory
 | 
			
		||||
            // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
 | 
			
		||||
            // assets and item asset id changes to complete.
 | 
			
		||||
            // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
 | 
			
		||||
            // multiple save requests.
 | 
			
		||||
            SetAppearanceAssets(sp.UUID, sp.Appearance);
 | 
			
		||||
 | 
			
		||||
            m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
 | 
			
		||||
        {
 | 
			
		||||
            IInventoryService invService = m_scene.InventoryService;
 | 
			
		||||
 | 
			
		||||
            if (invService.GetRootFolder(userID) != null)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    for (int j = 0; j < appearance.Wearables[j].Count; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (appearance.Wearables[i][j].ItemID == UUID.Zero)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        // Ignore ruth's assets
 | 
			
		||||
                        if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
 | 
			
		||||
                            continue;
 | 
			
		||||
                        InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
 | 
			
		||||
                        baseItem = invService.GetItem(baseItem);
 | 
			
		||||
 | 
			
		||||
                        if (baseItem != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.ErrorFormat(
 | 
			
		||||
                                "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
 | 
			
		||||
                                appearance.Wearables[i][j].ItemID, (WearableType)i);
 | 
			
		||||
 | 
			
		||||
                            appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Client Event Handlers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveAppearance(UUID agentid)
 | 
			
		||||
        {
 | 
			
		||||
            // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
 | 
			
		||||
            // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
 | 
			
		||||
            // number seperators.
 | 
			
		||||
            Culture.SetCurrentCulture();
 | 
			
		||||
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(agentid);
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
 | 
			
		||||
 | 
			
		||||
            // This could take awhile since it needs to pull inventory
 | 
			
		||||
            // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
 | 
			
		||||
            // assets and item asset id changes to complete.
 | 
			
		||||
            // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
 | 
			
		||||
            // multiple save requests.
 | 
			
		||||
            SetAppearanceAssets(sp.UUID, sp.Appearance);
 | 
			
		||||
 | 
			
		||||
            m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
 | 
			
		||||
        {
 | 
			
		||||
            IInventoryService invService = m_scene.InventoryService;
 | 
			
		||||
 | 
			
		||||
            if (invService.GetRootFolder(userID) != null)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    for (int j = 0; j < appearance.Wearables[j].Count; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (appearance.Wearables[i][j].ItemID == UUID.Zero)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        // Ignore ruth's assets
 | 
			
		||||
                        if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
 | 
			
		||||
                            continue;
 | 
			
		||||
                        InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
 | 
			
		||||
                        baseItem = invService.GetItem(baseItem);
 | 
			
		||||
 | 
			
		||||
                        if (baseItem != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.ErrorFormat(
 | 
			
		||||
                                "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
 | 
			
		||||
                                appearance.Wearables[i][j].ItemID, (WearableType)i);
 | 
			
		||||
 | 
			
		||||
                            appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Client Event Handlers
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Tell the client for this scene presence what items it should be wearing now
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="client"></param>
 | 
			
		||||
        private void Client_OnRequestWearables(IClientAPI client)
 | 
			
		||||
        {
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (sp != null)
 | 
			
		||||
            if (sp != null)
 | 
			
		||||
                client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
 | 
			
		||||
            else
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set appearance data (texture asset IDs and slider settings) received from a client
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="client"></param>
 | 
			
		||||
        /// <param name="texture"></param>
 | 
			
		||||
        /// <param name="visualParam"></param>
 | 
			
		||||
        private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (sp != null)
 | 
			
		||||
                SetAppearance(sp, textureEntry, visualParams);
 | 
			
		||||
            else
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set appearance data (texture asset IDs and slider settings) received from a client
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="client"></param>
 | 
			
		||||
        /// <param name="texture"></param>
 | 
			
		||||
        /// <param name="visualParam"></param>
 | 
			
		||||
        private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (sp != null)
 | 
			
		||||
                SetAppearance(sp, textureEntry, visualParams);
 | 
			
		||||
            else
 | 
			
		||||
                m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -523,7 +523,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
        /// <param name="client"></param>
 | 
			
		||||
        /// <param name="e"></param>
 | 
			
		||||
        private void Client_OnAvatarNowWearing(IClientAPI client, AvatarWearingArgs e)
 | 
			
		||||
        {
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing called for {0} ({1})", client.Name, client.AgentId);
 | 
			
		||||
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (sp == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -558,8 +558,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
                // of visual param and baked texture changes. When those complete, the new appearance will be sent
 | 
			
		||||
 | 
			
		||||
                QueueAppearanceSave(client.AgentId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
 | 
			
		|||
            
 | 
			
		||||
            AvatarFactoryModule afm = new AvatarFactoryModule();
 | 
			
		||||
            TestScene scene = SceneHelpers.SetupScene(assetCache);
 | 
			
		||||
            SceneHelpers.SetupSceneModules(scene, afm);
 | 
			
		||||
            SceneHelpers.SetupSceneModules(scene, afm);
 | 
			
		||||
            ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
 | 
			
		||||
 | 
			
		||||
            // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,8 @@ using OpenSim.Framework;
 | 
			
		|||
namespace OpenSim.Region.Framework.Interfaces
 | 
			
		||||
{
 | 
			
		||||
    public interface IAvatarFactoryModule
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -960,6 +960,46 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            return found;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Checks whether this region has a neighbour in the given direction.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="car"></param>
 | 
			
		||||
        /// <param name="fix"></param>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// An integer which represents a compass point.  N == 1, going clockwise until we reach NW == 8.
 | 
			
		||||
        /// Returns a positive integer if there is a region in that direction, a negative integer if not.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        public int HaveNeighbor(Cardinals car, ref int[] fix)
 | 
			
		||||
        {
 | 
			
		||||
            uint neighbourx = RegionInfo.RegionLocX;
 | 
			
		||||
            uint neighboury = RegionInfo.RegionLocY;
 | 
			
		||||
 | 
			
		||||
            int dir = (int)car;
 | 
			
		||||
 | 
			
		||||
            if (dir > 1 && dir < 5) //Heading East
 | 
			
		||||
                neighbourx++;
 | 
			
		||||
            else if (dir > 5) // Heading West
 | 
			
		||||
                neighbourx--;
 | 
			
		||||
 | 
			
		||||
            if (dir < 3 || dir == 8) // Heading North
 | 
			
		||||
                neighboury++;
 | 
			
		||||
            else if (dir > 3 && dir < 7) // Heading Sout
 | 
			
		||||
                neighboury--;
 | 
			
		||||
 | 
			
		||||
            int x = (int)(neighbourx * Constants.RegionSize);
 | 
			
		||||
            int y = (int)(neighboury * Constants.RegionSize);
 | 
			
		||||
            GridRegion neighbourRegion = GridService.GetRegionByPosition(RegionInfo.ScopeID, x, y);
 | 
			
		||||
 | 
			
		||||
            if (neighbourRegion == null)
 | 
			
		||||
            {
 | 
			
		||||
                fix[0] = (int)(RegionInfo.RegionLocX - neighbourx);
 | 
			
		||||
                fix[1] = (int)(RegionInfo.RegionLocY - neighboury);
 | 
			
		||||
                return dir * (-1);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                return dir;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Alias IncomingHelloNeighbour OtherRegionUp, for now
 | 
			
		||||
        public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2782,17 +2782,17 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
                    if (m_scene.TestBorderCross(pos2, Cardinals.S))
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.SW, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (m_scene.TestBorderCross(pos2, Cardinals.N))
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.NW, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.W, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (m_scene.TestBorderCross(pos2, Cardinals.E))
 | 
			
		||||
| 
						 | 
				
			
			@ -2800,28 +2800,28 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
                    if (m_scene.TestBorderCross(pos2, Cardinals.S))
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.SE, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (m_scene.TestBorderCross(pos2, Cardinals.N))
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.NE, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        needsTransit = true;
 | 
			
		||||
                        neighbor = HaveNeighbor(Cardinals.E, ref fix);
 | 
			
		||||
                        neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (m_scene.TestBorderCross(pos2, Cardinals.S))
 | 
			
		||||
                {
 | 
			
		||||
                    needsTransit = true;
 | 
			
		||||
                    neighbor = HaveNeighbor(Cardinals.S, ref fix);
 | 
			
		||||
                    neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix);
 | 
			
		||||
                }
 | 
			
		||||
                else if (m_scene.TestBorderCross(pos2, Cardinals.N))
 | 
			
		||||
                {
 | 
			
		||||
                    needsTransit = true;
 | 
			
		||||
                    neighbor = HaveNeighbor(Cardinals.N, ref fix);
 | 
			
		||||
                    neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Makes sure avatar does not end up outside region
 | 
			
		||||
| 
						 | 
				
			
			@ -2896,46 +2896,6 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Checks whether this region has a neighbour in the given direction.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="car"></param>
 | 
			
		||||
        /// <param name="fix"></param>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// An integer which represents a compass point.  N == 1, going clockwise until we reach NW == 8.
 | 
			
		||||
        /// Returns a positive integer if there is a region in that direction, a negative integer if not.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        protected int HaveNeighbor(Cardinals car, ref int[] fix)
 | 
			
		||||
        {
 | 
			
		||||
            uint neighbourx = m_scene.RegionInfo.RegionLocX;
 | 
			
		||||
            uint neighboury = m_scene.RegionInfo.RegionLocY;
 | 
			
		||||
 | 
			
		||||
            int dir = (int)car;
 | 
			
		||||
 | 
			
		||||
            if (dir > 1 && dir < 5) //Heading East
 | 
			
		||||
                neighbourx++;
 | 
			
		||||
            else if (dir > 5) // Heading West
 | 
			
		||||
                neighbourx--;
 | 
			
		||||
 | 
			
		||||
            if (dir < 3 || dir == 8) // Heading North
 | 
			
		||||
                neighboury++;
 | 
			
		||||
            else if (dir > 3 && dir < 7) // Heading Sout
 | 
			
		||||
                neighboury--;
 | 
			
		||||
 | 
			
		||||
            int x = (int)(neighbourx * Constants.RegionSize);
 | 
			
		||||
            int y = (int)(neighboury * Constants.RegionSize);
 | 
			
		||||
            GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y);
 | 
			
		||||
 | 
			
		||||
            if (neighbourRegion == null)
 | 
			
		||||
            {
 | 
			
		||||
                fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
 | 
			
		||||
                fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
 | 
			
		||||
                return dir * (-1);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                return dir;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Moves the agent outside the region bounds
 | 
			
		||||
        /// Tells neighbor region that we're crossing to it
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue