protected void RezAttachments(IScenePresence presence) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule> (); if (null == appearance.Appearance) { m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface <AvatarAttachments>(attachmentsPlugin); List <AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { int p = attach.AttachPoint; UUID itemID = attach.ItemID; try { RezSingleAttachmentFromInventory(presence.ControllingClient, itemID, p); } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); } } }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List <AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, 0); } catch (Exception e) { MainConsole.Instance.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e); } } }); }
private void DetachSingleAttachmentGroupToInventoryInternal(UUID itemID, IClientAPI remoteClient, bool fireEvent, ISceneEntity group) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); } IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface <AvatarAttachments>(); if (attModule != null) { attModule.RemoveAttachment(group); } if (attModule != null) { presence.SetAttachments(attModule.Get()); } } MainConsole.Instance.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } if (group.HasGroupChanged) { UpdateKnownItem(remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); } }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat( "[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List <AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); MainConsole.Instance.InfoFormat( "[ATTACHMENTS MODULE]: Found {0} attachments to attach to avatar {1}", attachments.Count, presence.Name); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, attach.AssetID, 0, false); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ATTACHMENT]: Unable to rez attachment: {0}", e); } } presence.AttachmentsLoaded = true; lock (_usersToSendAttachmentsToWhenLoaded) { if (_usersToSendAttachmentsToWhenLoaded.ContainsKey(presence.UUID)) { foreach (var id in _usersToSendAttachmentsToWhenLoaded[presence.UUID]) { SendAttachmentsToPresence(id, presence); } _usersToSendAttachmentsToWhenLoaded.Remove(presence.UUID); } } }); }
/// <summary> /// Get all of the attachments for the given avatar /// </summary> /// <param name="avatarID">The avatar whose attachments will be returned</param> /// <returns>The avatar's attachments as SceneObjectGroups</returns> public ISceneEntity[] GetAttachmentsForAvatar(UUID avatarID) { ISceneEntity[] attachments = new ISceneEntity[0]; IScenePresence presence = m_scene.GetScenePresence(avatarID); if (presence != null) { AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attachments = attPlugin.Get(); } } return(attachments); }
public void RezAttachments (IScenePresence presence) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule> (); if(null == appearance || null == appearance.Appearance) { m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface <AvatarAttachments>(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments (); foreach (AvatarAttachment attach in attachments) { int p = attach.AttachPoint; UUID itemID = attach.ItemID; try { RezSingleAttachmentFromInventory(presence.ControllingClient, itemID, p); } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); } } foreach(IScenePresence sp in presence.Scene.GetScenePresences()) sp.SceneViewer.QueuePresenceForFullUpdate(presence, true); }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat( "[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); MainConsole.Instance.InfoFormat( "[ATTACHMENTS MODULE]: Found {0} attachments to attach to avatar {1}", attachments.Count, presence.Name); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, attach.AssetID, 0, false); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ATTACHMENT]: Unable to rez attachment: {0}", e); } } presence.AttachmentsLoaded = true; lock (_usersToSendAttachmentsToWhenLoaded) { if (_usersToSendAttachmentsToWhenLoaded.ContainsKey(presence.UUID)) { foreach (var id in _usersToSendAttachmentsToWhenLoaded[presence.UUID]) { SendAttachmentsToPresence(id, presence); } _usersToSendAttachmentsToWhenLoaded.Remove(presence.UUID); } } }); }
public void ResumeAvatar(IScenePresence presence) { Util.FireAndForget(delegate { IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule>(); if (null == appearance || null == appearance.Appearance) { MainConsole.Instance.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); presence.RegisterModuleInterface(attachmentsPlugin); List<AvatarAttachment> attachments = appearance.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { try { RezSingleAttachmentFromInventory(presence.ControllingClient, attach.ItemID, 0); } catch (Exception e) { MainConsole.Instance.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e); } } }); }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="assetID" /> /// <param name="forceUpdatePrim">Force updating of the prim the next time the user attempts to deattach it</param> /// <param name="isTempAttach">Is a temporary attachment</param> protected void FindAttachmentPoint(IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, UUID assetID, bool forceUpdatePrim, bool isTempAttach) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if (!m_allowMultipleAttachments) { hasMultipleAttachmentsSet = false; } AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2} localID {3}", group.Name, remoteClient.Name, AttachmentPt, group.LocalId); //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence == null) { return; } UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if (!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) { DetachSingleAttachmentToInventory(itemID, remoteClient); } } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List <ISceneChildEntity> parts = group.ChildrenEntities(); foreach (ISceneChildEntity t in parts) { t.AttachedAvatar = presence.UUID; } if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId(presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (!isTempAttach) { if (itemID == UUID.Zero) { //Delete the object inworld to inventory List <ISceneEntity> groups = new List <ISceneEntity>(1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (inventoryAccess != null) { inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); } if (UUID.Zero == itemID) { MainConsole.Instance.Error( "[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (assetID == UUID.Zero) { assetID = m_scene.InventoryService.GetItemAssetID(remoteClient.AgentId, itemID); //Update the ItemID with the new item group.SetFromItemID(itemID, assetID); } } else { // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); group.RootChild.FromUserInventoryItemID = UUID.Zero; } AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment(group); presence.SetAttachments(attPlugin.Get()); if (!isTempAttach) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance.SetAttachments(attPlugin.Get()); AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = changedPositionPoint || forceUpdatePrim; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
protected void RezAttachments(ScenePresence presence) { if (null == presence.Appearance) { m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", presence.UUID); return; } //Create the avatar attachments plugin for the av AvatarAttachments attachmentsPlugin = new AvatarAttachments(presence); List<AvatarAttachment> attachments = presence.Appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { int p = attach.AttachPoint; UUID itemID = attach.ItemID; try { RezSingleAttachmentFromInventory(presence.ControllingClient, itemID, p); } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); } } }
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? protected void DetachSingleAttachmentToInventoryInternal(UUID itemID, IClientAPI remoteClient, bool fireEvent) { if (itemID == UUID.Zero) // If this happened, someone made a mistake.... { return; } // We can NOT use the dictionaries here, as we are looking // for an entity by the fromAssetID, which is NOT the prim UUID ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); foreach (ISceneEntity group in attachments) { if (group.RootChild.FromUserInventoryItemID == itemID) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); } IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface <AvatarAttachments>(); if (attModule != null) { attModule.RemoveAttachment(group); } } m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } UpdateKnownItem(remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); IBackupModule backup = m_scene.RequestModuleInterface <IBackupModule>(); if (backup != null) { backup.DeleteSceneObjects(new ISceneEntity[1] { group }, true); } return; //All done, end } } }
public ISceneEntity RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, int AttachmentPt) { MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); IInventoryAccessModule invAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (invAccess != null) { SceneObjectGroup objatt = invAccess.CreateObjectFromInventory(remoteClient, itemID); if (objatt != null) { #region Set up object for attachment status InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); if (item == null) { return(null); } objatt.RootPart.Flags |= PrimFlags.Phantom; objatt.RootPart.IsAttachment = true; objatt.SetFromItemID(itemID, item.AssetID); // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. objatt.RootPart.Name = item.Name; objatt.RootPart.Description = item.Description; List <SceneObjectPart> partList = new List <SceneObjectPart>(objatt.ChildrenList); foreach (SceneObjectPart part in partList) { part.AttachedAvatar = remoteClient.AgentId; } objatt.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId); if (objatt.RootPart.OwnerID != item.Owner) { //Need to kill the for sale here objatt.RootPart.ObjectSaleType = 0; objatt.RootPart.SalePrice = 10; if (m_scene.Permissions.PropagatePermissions()) { if ((item.CurrentPermissions & 8) != 0) { foreach (SceneObjectPart part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } objatt.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); } } objatt.RootPart.TrimPermissions(); objatt.RootPart.IsAttachment = true; objatt.IsDeleted = false; //Update the ItemID with the new item objatt.SetFromItemID(itemID, item.AssetID); //DO NOT SEND THIS KILL ENTITY // If we send this, when someone copies an inworld object, then wears it, the inworld objects disapepars // If a bug is caused by this, we need to figure out some other workaround. //SendKillEntity(objatt.RootChild); //We also have to reset the IDs so that it doesn't have the same IDs as one inworld (possibly)! m_scene.SceneGraph.PrepPrimForAdditionToScene(objatt); m_scene.Entities.Add(objatt); //If we updated the attachment, we need to save the change IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); bool save = appearance.Appearance.CheckWhetherAttachmentChanged(AttachmentPt, item.ID, item.AssetID); attPlugin.AddAttachment(objatt); appearance.Appearance.SetAttachments(attPlugin.Get()); if (save) { AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } MainConsole.Instance.InfoFormat( "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2} localID {3}", objatt.Name, remoteClient.Name, AttachmentPt, objatt.LocalId); FindAttachmentPoint(remoteClient, objatt.LocalId, objatt, AttachmentPt, item); } else { objatt = null;//Presence left, kill the attachment } #endregion } else { MainConsole.Instance.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", itemID, remoteClient.Name, AttachmentPt); } return(objatt); } return(null); }