/// <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 }
/// <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); }
/// <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; }
/// <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); }