/// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
        {
            IScenePresence sp = m_scene.GetScenePresence(client.AgentId);
            if (sp == null)
            {
                m_log.WarnFormat("[AvatarFactory]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
                return;
            }

            m_log.DebugFormat("[AvatarFactory]: AvatarIsWearing called for {0}", client.AgentId);

            // operate on a copy of the appearance so we don't have to lock anything
            IAvatarAppearanceModule appearance = sp.RequestModuleInterface<IAvatarAppearanceModule> ();
            AvatarAppearance avatAppearance = new AvatarAppearance (appearance.Appearance, false);

            IOpenRegionSettingsModule module = m_scene.RequestModuleInterface<IOpenRegionSettingsModule> ();

            bool NeedsRebake = false;
            if (module != null && module.EnableTeenMode)
            {
                foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
                {
                    if (wear.Type == 10 & wear.ItemID == UUID.Zero && module.DefaultUnderpants != UUID.Zero)
                    {
                        NeedsRebake = true;
                        wear.ItemID = module.DefaultUnderpants;
                        InventoryItemBase item = new InventoryItemBase(UUID.Random());
                        item.InvType = (int)InventoryType.Wearable;
                        item.AssetType = (int)AssetType.Clothing;
                        item.Name = "Default Underpants";
                        item.Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, AssetType.Clothing).ID;
                        item.Owner = client.AgentId;
                        item.CurrentPermissions = 0;//Locked
                        item.CreatorId = UUID.Zero.ToString();
                        item.AssetID = module.DefaultUnderpants;
                        client.SendInventoryItemCreateUpdate(item, 0);
                    }
                    else if (wear.Type == 10 & wear.ItemID == UUID.Zero)
                    {
                        NeedsRebake = true;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random ());
                        item.InvType = (int)InventoryType.Wearable;
                        item.AssetType = (int)AssetType.Clothing;
                        item.Name = "Default Underpants";
                        item.Folder = m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, AssetType.Clothing).ID;
                        item.Owner = client.AgentId;
                        item.CurrentPermissions = 0;//Locked
                        if (m_underPantsUUID == UUID.Zero)
                        {
                            m_underPantsUUID = UUID.Random ();
                            AssetBase asset = new AssetBase(m_underPantsUUID, "Default Underpants", AssetType.Clothing,
                                                            UUID.Zero) {Data = Utils.StringToBytes(m_defaultUnderPants)};
                            asset.FillHash();
                            asset.ID = m_scene.AssetService.Store(asset);
                            m_underPantsUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString ();
                        item.AssetID = m_underPantsUUID;
                        m_scene.InventoryService.AddItem(item);
                        client.SendInventoryItemCreateUpdate(item, 0);
                        wear.ItemID = item.ID;
                    }
                    if (wear.Type == 11 && wear.ItemID == UUID.Zero && module.DefaultUndershirt != UUID.Zero)
                    {
                        NeedsRebake = true;
                        wear.ItemID = module.DefaultUndershirt;
                        InventoryItemBase item = new InventoryItemBase(UUID.Random());
                        item.InvType = (int)InventoryType.Wearable;
                        item.AssetType = (int)AssetType.Clothing;
                        item.Name = "Default Undershirt";
                        item.Folder = m_scene.InventoryService.GetFolderForType(client.AgentId, InventoryType.Wearable, AssetType.Clothing).ID;
                        item.Owner = client.AgentId;
                        item.CurrentPermissions = 0;//Locked
                        item.CreatorId = UUID.Zero.ToString();
                        item.AssetID = module.DefaultUndershirt;
                        client.SendInventoryItemCreateUpdate(item, 0);
                    }
                    else if (wear.Type == 11 & wear.ItemID == UUID.Zero)
                    {
                        NeedsRebake = true;
                        InventoryItemBase item = new InventoryItemBase (UUID.Random());
                        item.InvType = (int)InventoryType.Wearable;
                        item.AssetType = (int)AssetType.Clothing;
                        item.Name = "Default Undershirt";
                        item.Folder = m_scene.InventoryService.GetFolderForType (client.AgentId, InventoryType.Wearable, AssetType.Clothing).ID;
                        item.Owner = client.AgentId;
                        item.CurrentPermissions = 0;//Locked
                        if (m_underShirtUUID == UUID.Zero)
                        {
                            m_underShirtUUID = UUID.Random ();
                            AssetBase asset = new AssetBase(m_underShirtUUID, "Default Undershirt", AssetType.Clothing,
                                                            UUID.Zero) {Data = Utils.StringToBytes(m_defaultUnderShirt)};
                            asset.FillHash();
                            asset.ID = m_scene.AssetService.Store(asset);
                            m_underShirtUUID = asset.ID;
                        }
                        item.CreatorId = UUID.Zero.ToString ();
                        item.AssetID = m_underShirtUUID;
                        m_scene.InventoryService.AddItem(item);
                        client.SendInventoryItemCreateUpdate(item, 0);
                        wear.ItemID = item.ID;
                    }
                }
            }

            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                {
                    /*if (incomingLinks.ContainsKey (wear.ItemID))
                    {
                        wear.ItemID = incomingLinks[wear.ItemID];
                    }*/
                    avatAppearance.Wearables[wear.Type].Add (wear.ItemID, UUID.Zero);
                }
            }

            avatAppearance.GetAssetsFrom (appearance.Appearance);
            
            // This could take awhile since it needs to pull inventory
            SetAppearanceAssets(sp.UUID, ref avatAppearance);

            // could get fancier with the locks here, but in the spirit of "last write wins"
            // 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
            appearance.Appearance = avatAppearance;
            if (NeedsRebake)
            {
                //Tell the client about the new things it is wearing
                sp.ControllingClient.SendWearables (appearance.Appearance.Wearables, appearance.Appearance.Serial);
                //Then forcefully tell it to rebake
                for (int i = 0; i < appearance.Appearance.Texture.FaceTextures.Length; i++)
                {
                    Primitive.TextureEntryFace face = (appearance.Appearance.Texture.FaceTextures[i]);

                    if (face != null)
                        sp.ControllingClient.SendRebakeAvatarTextures (face.TextureID);
                }
            }
            QueueAppearanceSave(sp.UUID);
            //Send the wearables HERE so that the client knows what it is wearing
            //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial);
            //Do not save or send the appearance! The client loops back and sends a bunch of SetAppearance
            //  (handled above) and that takes care of it
        }
Beispiel #2
0
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
        {
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
            if (sp == null)
            {
                m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
                return;
            }

//            m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId);

            AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);

            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                    avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
            }

            avatAppearance.GetAssetsFrom(sp.Appearance);

            // This could take awhile since it needs to pull inventory
            SetAppearanceAssets(sp.UUID, ref avatAppearance);

            sp.Appearance = avatAppearance;
            m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
        }
Beispiel #3
0
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
        {
            IClientAPI clientView = (IClientAPI)sender;
            ScenePresence avatar = m_scene.GetScenePresence(clientView.AgentId);
            
            if (avatar == null) 
            {
                m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event");
                return;
            }

            CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId);

            AvatarAppearance avatAppearance = null;
            if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance)) 
            {
                m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence");
                avatAppearance = avatar.Appearance;
            }
            
            //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name);
            
            if (profile != null)
            {
                if (profile.RootFolder != null)
                {
                    foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
                    {
                        if (wear.Type < 13)
                        {
                            avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
                        }
                    }
                    
                    SetAppearanceAssets(profile, ref avatAppearance);

                    m_scene.CommsManager.AvatarService.UpdateUserAppearance(clientView.AgentId, avatAppearance);
                    avatar.Appearance = avatAppearance;
                }
                else
                {
                    m_log.WarnFormat(
                        "[APPEARANCE]: Inventory has not yet been received for {0}, cannot set wearables", 
                        clientView.Name);
                }
            }
            else
            {
                m_log.WarnFormat("[APPEARANCE]: Cannot set wearables for {0}, no user profile found", clientView.Name);
            }
        }
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
        {
            IClientAPI clientView = (IClientAPI)sender;
            ScenePresence avatar = m_scene.GetScenePresence(clientView.AgentId);
            
            if (avatar == null) 
            {
                m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event");
                return;
            }

            CachedUserInfo profile = m_scene.CommsManager.UserService.GetUserDetails(clientView.AgentId);
            if (profile != null)
            {
                // we need to clean out the existing textures
                AvatarAppearance appearance = avatar.Appearance;
                avatar.Appearance.ResetAppearance();

                List<AvatarWearable> wearables = new List<AvatarWearable>();
                lock (_currentlyWaitingCOFBuilds)
                {
                    //Check to see whether the client can manage itself
                    if (_cofSyncEnabled && !_viewer2Users.Contains(clientView.AgentId))
                    {
                        foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
                        {
                            wearables.Add(new AvatarWearable(wear.Type, wear.ItemID, UUID.Zero));
                            AvatarWearable oldWearable = appearance.GetWearableOfType(wear.Type);
                            if (wear.ItemID != UUID.Zero)
                            {
                                if (oldWearable == null || oldWearable.ItemID == UUID.Zero || wear.ItemID != oldWearable.ItemID)
                                {
                                    bool add = false;
                                    Dictionary<UUID, BuildCOF> waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                    if ((add = !_currentlyWaitingCOFBuilds.TryGetValue(clientView.AgentId, out waitingCOFs)))
                                        waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                    //Make sure that the new item is added
                                    if (waitingCOFs.ContainsKey(wear.ItemID))
                                    {
                                        BuildCOF cof = waitingCOFs[wear.ItemID];
                                        cof.SetWearableToLookFor(wear.ItemID, m_scene, clientView.AgentId, true);
                                        if (cof.Finished())
                                            waitingCOFs.Remove(wear.ItemID);
                                    }
                                    else
                                    {
                                        BuildCOF cof = new BuildCOF(ClearWaitingCOF);
                                        cof.SetWearableToLookFor(wear.ItemID, m_scene, clientView.AgentId, true);
                                        waitingCOFs.Add(wear.ItemID, cof);
                                    }
                                    if (add)
                                        _currentlyWaitingCOFBuilds.Add(clientView.AgentId, waitingCOFs);
                                }
                                if (oldWearable != null && oldWearable.ItemID != UUID.Zero && wear.ItemID != oldWearable.ItemID)
                                {
                                    bool add = false;
                                    Dictionary<UUID, BuildCOF> waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                    if ((add = !_currentlyWaitingCOFBuilds.TryGetValue(clientView.AgentId, out waitingCOFs)))
                                        waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                    //Check for removal of old item
                                    if (waitingCOFs.ContainsKey(oldWearable.ItemID))
                                    {
                                        BuildCOF cof = waitingCOFs[oldWearable.ItemID];
                                        cof.SetWearableToLookFor(oldWearable.ItemID, m_scene, clientView.AgentId, false);
                                        if (cof.Finished())
                                            waitingCOFs.Remove(oldWearable.ItemID);
                                    }
                                    else
                                    {
                                        BuildCOF cof = new BuildCOF(ClearWaitingCOF);
                                        cof.SetWearableToLookFor(oldWearable.ItemID, m_scene, clientView.AgentId, false);
                                        waitingCOFs.Add(oldWearable.ItemID, cof);
                                    }
                                    if (add)
                                        _currentlyWaitingCOFBuilds.Add(clientView.AgentId, waitingCOFs);
                                }
                            }
                            else if (oldWearable != null && oldWearable.ItemID != UUID.Zero)
                            {
                                bool add = false;
                                Dictionary<UUID, BuildCOF> waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                if ((add = !_currentlyWaitingCOFBuilds.TryGetValue(clientView.AgentId, out waitingCOFs)))
                                    waitingCOFs = new Dictionary<UUID, BuildCOF>();
                                //Remove the item if it was just removed
                                if (waitingCOFs.ContainsKey(oldWearable.ItemID))
                                {
                                    BuildCOF cof = waitingCOFs[oldWearable.ItemID];
                                    cof.SetWearableToLookFor(oldWearable.ItemID, m_scene, clientView.AgentId, false);
                                    if (cof.Finished())
                                        waitingCOFs.Remove(oldWearable.ItemID);
                                }
                                else
                                {
                                    BuildCOF cof = new BuildCOF(ClearWaitingCOF);
                                    cof.SetWearableToLookFor(oldWearable.ItemID, m_scene, clientView.AgentId, false);
                                    waitingCOFs.Add(oldWearable.ItemID, cof);
                                }
                                if (add)
                                    _currentlyWaitingCOFBuilds.Add(clientView.AgentId, waitingCOFs);
                            }
                        }
                    }
                    else
                    {
                        foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
                            wearables.Add(new AvatarWearable(wear.Type, wear.ItemID, UUID.Zero));
                    }
                }
                // Wearables are a stack. The entries we have represent the current "top" stack state.  Apply them

                SetAppearanceAssets(profile, ref wearables, clientView);
                avatar.Appearance.SetWearables(wearables);
                this.UpdateDatabase(clientView.AgentId, avatar.Appearance, null, null);
            }
            else
            {
                m_log.WarnFormat("[APPEARANCE]: Cannot set wearables for {0}, no user profile found", clientView.Name);
            }
        }
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
        {
            IClientAPI clientView = (IClientAPI)sender;
            ScenePresence avatar = m_scene.GetScenePresence(clientView.AgentId);
            
            if (avatar == null) 
            {
                m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event");
                return;
            }

            AvatarAppearance avatAppearance = null;
            if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance)) 
            {
                m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence");
                avatAppearance = avatar.Appearance;
            }
            
            //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name);
            
            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < 13)
                {
                    avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
                }
            }
            
            SetAppearanceAssets(avatar.UUID, ref avatAppearance);

            m_scene.CommsManager.AvatarService.UpdateUserAppearance(clientView.AgentId, avatAppearance);
            avatar.Appearance = avatAppearance;
        }
Beispiel #6
0
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <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)
            {
                m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing unable to find presence for {0}", client.AgentId);
                return;
            }

            // we need to clean out the existing textures
            sp.Appearance.ResetAppearance();

            // operate on a copy of the appearance so we don't have to lock anything yet
            AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);

            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                    avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
            }

            avatAppearance.GetAssetsFrom(sp.Appearance);

            lock (m_setAppearanceLock)
            {
                // Update only those fields that we have changed. This is important because the viewer
                // often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
                // shouldn't overwrite the changes made in SetAppearance.
                sp.Appearance.Wearables = avatAppearance.Wearables;
                sp.Appearance.Texture = avatAppearance.Texture;

                // 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

                QueueAppearanceSave(client.AgentId);
            }
        }
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
        {
            //m_log.DebugFormat("[APPEARANCE]: AvatarIsWearing");

            IClientAPI clientView = (IClientAPI)sender;
            ScenePresence sp = m_scene.GetScenePresence(clientView.AgentId);

            if (sp == null)
            {
                m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event");
                return;
            }

            AvatarAppearance avatAppearance = sp.Appearance;
            //if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance)) 
            //{
            //    m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence");
            //    avatAppearance = sp.Appearance;
            //}

            //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name);

            IOpenRegionSettingsModule module = m_scene.RequestModuleInterface<IOpenRegionSettingsModule>();

            bool NeedsRebake = false;
            if (module != null && module.EnableTeenMode)
            {
                foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
                {
                    if (wear.Type == 10)
                    {
                        if (wear.ItemID == UUID.Zero && module.DefaultUnderpants != UUID.Zero)
                        {
                            NeedsRebake = true;
                            wear.ItemID = module.DefaultUnderpants;
                        }
                    }
                    if (wear.Type == 11)
                    {
                        if (wear.ItemID == UUID.Zero && module.DefaultUndershirt != UUID.Zero)
                        {
                            NeedsRebake = true;
                            wear.ItemID = module.DefaultUndershirt;
                        }
                    }
                }
            }

            foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
            {
                if (wear.Type < 15)
                {
                    avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
                }
            }

            SetAppearanceAssets(sp.UUID, ref avatAppearance);
            sp.Appearance = avatAppearance;

            if (NeedsRebake)
            {
                sp.SendWearables();
                for (int i = 0; i < sp.Appearance.Texture.FaceTextures.Length; i++)
                {
                    Primitive.TextureEntryFace face = (sp.Appearance.Texture.FaceTextures[i]);

                    if (face != null)
                    {
                        sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
                    }
                }
            }


            AvatarData adata = new AvatarData(avatAppearance);
            if (!m_scene.AvatarService.SetAvatar(clientView.AgentId, adata))
                m_log.Error("[AVFACTORY]: Error saving appearance for " + sp.Name + ".");
        }
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
        {
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
            if (sp == null)
            {
                m_log.WarnFormat("[AvatarFactory]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
                return;
            }

            m_log.DebugFormat("[AvatarFactory]: 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)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                    avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
            }

            avatAppearance.GetAssetsFrom(sp.Appearance);

            // This could take awhile since it needs to pull inventory
            SetAppearanceAssets(sp.UUID, ref avatAppearance);

            // could get fancier with the locks here, but in the spirit of "last write wins"
            // 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;
            //Send the wearables HERE so that the client knows what it is wearing
            //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial);
            //Do not save or send the appearance! The client loops back and sends a bunch of SetAppearance
            //  (handled above) and that takes care of it
        }
        /// <summary>
        /// Update what the avatar is wearing using an item from their inventory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
        {
            ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
            if (sp == null)
            {
                m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
                return;
            }

            // 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)
            {
                if (wear.Type < AvatarWearable.MAX_WEARABLES)
                    avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
            }

            avatAppearance.GetAssetsFrom(sp.Appearance);

            // This could take awhile since it needs to pull inventory
            SetAppearanceAssets(sp.UUID, ref avatAppearance);

            // could get fancier with the locks here, but in the spirit of "last write wins"
            // 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;
            QueueAppearanceSave(client.AgentId);
        }