From 911e63765c7cea748b5ae2227f5c1d6ff131d329 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sun, 27 Apr 2008 20:10:28 +0000 Subject: [PATCH] * Single Attachments now work from inventory. You can attach from inventory and detach from inventory. * Detaching from right clicking in world, detaches to your inventory. * If you go up to a prim and attach it from in world, it appears in your inventory. * Attachment placement is saved when you detach them. * Choosing wear remembers your last attachment point from inventory. * Wrote a method to update an inventory item's asset and sends the updated inventory item to the Client * Wrote a recursive method to find the folder of a known existing inventory item. * Removed a block on physics object position on creation. This might crash a region or two, let us know via Mantis if your region crashes because of a physics out of bounds error. * Drop doesn't work. The menu item doesn't even come up. Don't know why :P. --- .../Communications/Cache/CachedUserInfo.cs | 9 ++ OpenSim/Framework/IClientAPI.cs | 1 + OpenSim/Region/ClientStack/ClientView.cs | 19 +++- .../Region/Environment/Scenes/InnerScene.cs | 72 +++++++++++--- .../Environment/Scenes/Scene.Inventory.cs | 99 ++++++++++++++++++- OpenSim/Region/Environment/Scenes/Scene.cs | 6 ++ .../Environment/Scenes/SceneObjectGroup.cs | 26 ++++- .../Environment/Scenes/ScenePresence.cs | 10 ++ .../Examples/SimpleModule/MyNpcCharacter.cs | 1 + OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 32 +++--- 10 files changed, 241 insertions(+), 34 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index f1268d5236..97493668ed 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -272,8 +272,13 @@ namespace OpenSim.Framework.Communications.Cache { if (!RootFolder.Items.ContainsKey(itemInfo.ID)) { + RootFolder.Items.Add(itemInfo.ID, itemInfo); } + else + { + RootFolder.Items[itemInfo.ID] = itemInfo; + } } } else @@ -287,6 +292,10 @@ namespace OpenSim.Framework.Communications.Cache { folder.Items.Add(itemInfo.ID, itemInfo); } + else + { + folder.Items[itemInfo.ID] = itemInfo; + } } } } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 174d20aedc..fb32397548 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -455,6 +455,7 @@ namespace OpenSim.Framework event SetAppearance OnSetAppearance; event AvatarNowWearing OnAvatarNowWearing; event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; + event UUIDNameRequest OnDetachAttachmentIntoInv; event ObjectAttach OnObjectAttach; event ObjectDeselect OnObjectDetach; event StartAnim OnStartAnim; diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index fb9d638ec9..94de013868 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -145,6 +145,7 @@ namespace OpenSim.Region.ClientStack private SetAppearance handlerSetAppearance = null; //OnSetAppearance; private AvatarNowWearing handlerAvatarNowWearing = null; //OnAvatarNowWearing; private RezSingleAttachmentFromInv handlerRezSingleAttachment = null; //OnRezSingleAttachmentFromInv; + private UUIDNameRequest handlerDetachAttachmentIntoInv = null; // Detach attachment! private ObjectAttach handlerObjectAttach = null; //OnObjectAttach; private SetAlwaysRun handlerSetAlwaysRun = null; //OnSetAlwaysRun; private GenericCall2 handlerCompleteMovementToRegion = null; //OnCompleteMovementToRegion; @@ -690,6 +691,7 @@ namespace OpenSim.Region.ClientStack public event SetAppearance OnSetAppearance; public event AvatarNowWearing OnAvatarNowWearing; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; + public event UUIDNameRequest OnDetachAttachmentIntoInv; public event ObjectAttach OnObjectAttach; public event ObjectDeselect OnObjectDetach; public event GenericCall2 OnCompleteMovementToRegion; @@ -3441,6 +3443,18 @@ namespace OpenSim.Region.ClientStack rez.ObjectData.AttachmentPt, rez.ObjectData.ItemFlags, rez.ObjectData.NextOwnerMask); } + break; + case PacketType.DetachAttachmentIntoInv: + handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; + if (handlerDetachAttachmentIntoInv != null) + { + DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack; + + LLUUID itemID = detachtoInv.ObjectData.ItemID; + LLUUID ATTACH_agentID = detachtoInv.ObjectData.AgentID; + + handlerDetachAttachmentIntoInv(itemID, this); + } break; case PacketType.ObjectAttach: if (OnObjectAttach != null) @@ -3451,7 +3465,10 @@ namespace OpenSim.Region.ClientStack if (handlerObjectAttach != null) { - handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation); + if (att.ObjectData.Length > 0) + { + handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation); + } } } diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index e76cf70e18..104ae485d1 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -304,7 +304,9 @@ namespace OpenSim.Region.Environment.Scenes if (((SceneObjectGroup)obj).LocalId == objectLocalID) { SceneObjectGroup group = (SceneObjectGroup)obj; - group.DetachToGround(); + + //group.DetachToGround(); + DetachSingleAttachmentToInv(group.GetFromAssetID(),remoteClient); } } } @@ -339,6 +341,33 @@ namespace OpenSim.Region.Environment.Scenes } + // What makes this method odd and unique is it tries to detach using an LLUUID.... Yay for standards. + // To LocalId or LLUUID, *THAT* is the question. How now Brown LLUUID?? + public void DetachSingleAttachmentToInv(LLUUID itemID, IClientAPI remoteClient) + { + + if (itemID == LLUUID.Zero) // If this happened, someone made a mistake.... + return; + + List EntityList = GetEntities(); + + foreach (EntityBase obj in EntityList) + { + if (obj is SceneObjectGroup) + { + if (((SceneObjectGroup)obj).GetFromAssetID() == itemID) + { + SceneObjectGroup group = (SceneObjectGroup)obj; + group.DetachToInventoryPrep(); + m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); + m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(),group.OwnerID); + m_parentScene.DeleteSceneObjectGroup(group); + } + } + } + + } + public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot, LLVector3 attachPos) { List EntityList = GetEntities(); @@ -349,22 +378,37 @@ namespace OpenSim.Region.Environment.Scenes if (((SceneObjectGroup)obj).LocalId == objectLocalID) { SceneObjectGroup group = (SceneObjectGroup)obj; + + // 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. + if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) + { + + attachPos = LLVector3.Zero; + } + + // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { + // Check object for stored attachment point AttachmentPt = (uint)group.GetAttachmentPoint(); - - - // if we still didn't find a suitable attachment point....... - if (AttachmentPt == 0) - { - AttachmentPt = (uint)AttachmentPoint.LeftHand; - attachPos = LLVector3.Zero; - } - + } + // if we still didn't find a suitable attachment point....... + if (AttachmentPt == 0) + { + // Stick it on left hand with Zero Offset from the attachment point. + AttachmentPt = (uint)AttachmentPoint.LeftHand; + attachPos = LLVector3.Zero; + } + m_log.Debug("[ATTACH]: Using attachpoint: " + AttachmentPt.ToString()); + + + // Saves and gets assetID if (group.GetFromAssetID() == LLUUID.Zero) { @@ -1071,12 +1115,12 @@ namespace OpenSim.Region.Environment.Scenes if (group != null) { LLVector3 oldPos = group.AbsolutePosition; - if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos)) + if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment) { group.SendGroupTerseUpdate(); return; } - if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID)) + if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment) { group.UpdateSinglePosition(pos, localID); } @@ -1102,12 +1146,12 @@ namespace OpenSim.Region.Environment.Scenes } else { - if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos)) + if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment) { group.SendGroupTerseUpdate(); return; } - if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID)) + if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment) { group.UpdateGroupPosition(pos); } diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index a3e26b4f11..b5e2c40ad3 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1002,6 +1002,93 @@ namespace OpenSim.Region.Environment.Scenes } } } + public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID assetID, LLUUID agentID) + { + SceneObjectGroup objectGroup = grp; + if (objectGroup != null) + { + string sceneObjectXml = objectGroup.ToXmlString(); + + CachedUserInfo userInfo = + CommsManager.UserProfileCacheService.GetUserDetails(agentID); + if (userInfo != null) + { + Queue searchfolders = new Queue(); + searchfolders.Enqueue(userInfo.RootFolder); + + LLUUID foundFolder = userInfo.RootFolder.ID; + + // search through folders to find the asset. + while (searchfolders.Count > 0) + { + + InventoryFolderImpl fld = searchfolders.Dequeue(); + lock (fld) + { + if (fld != null) + { + if (fld.Items.ContainsKey(assetID)) + { + foundFolder = fld.ID; + searchfolders.Clear(); + break; + } + else + { + foreach (InventoryFolderImpl subfld in fld.SubFolders.Values) + { + searchfolders.Enqueue(subfld); + } + } + } + } + } + AssetBase asset = CreateAsset( + objectGroup.GetPartName(objectGroup.LocalId), + objectGroup.GetPartDescription(objectGroup.LocalId), + (sbyte)InventoryType.Object, + (sbyte)AssetType.Object, + Helpers.StringToField(sceneObjectXml)); + AssetCache.AddAsset(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Creator = objectGroup.RootPart.CreatorID; + item.Owner = agentID; + item.ID = assetID; + item.AssetID = asset.FullID; + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + item.InvType = asset.InvType; + + // Sticking it in root folder for now.. objects folder later? + + item.Folder = foundFolder;// DeRezPacket.AgentBlock.DestinationID; + item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; + if (agentID != objectGroup.RootPart.OwnerID) + { + item.BasePermissions = objectGroup.RootPart.NextOwnerMask; + item.CurrentPermissions = objectGroup.RootPart.NextOwnerMask; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + } + else + { + item.BasePermissions = objectGroup.RootPart.BaseMask; + item.CurrentPermissions = objectGroup.RootPart.OwnerMask; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + } + + userInfo.AddItem(agentID, item); + + // this gets called when the agent loggs off! + if (remoteClient != null) + { + remoteClient.SendInventoryItemCreateUpdate(item); + } + + } + } + } public LLUUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID AgentId) { SceneObjectGroup objectGroup = grp; @@ -1184,7 +1271,17 @@ namespace OpenSim.Region.Environment.Scenes } rootPart.TrimPermissions(); - group.ApplyPhysics(m_physicalPrim); + + if (!attachment) + { + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + group.RootPart.Shape.State = (byte)0; + } + group.ApplyPhysics(m_physicalPrim); + } + + group.StartScripts(); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index a9fa93ec7e..f94aec74a4 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1471,6 +1471,11 @@ namespace OpenSim.Region.Environment.Scenes ScenePresence sp = GetScenePresence(grp.OwnerID); if (sp != null) { + // hack assetID until we get assetID into the XML format. + // LastOwnerID is used for group deeding, so when you do stuff + // with the deeded object, it goes back to them + + grp.SetFromAssetID(grp.RootPart.LastOwnerID); m_innerScene.AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition); } } @@ -1560,6 +1565,7 @@ namespace OpenSim.Region.Environment.Scenes client.OnDeRezObject += DeRezObject; client.OnRezObject += RezObject; client.OnRezSingleAttachmentFromInv += m_innerScene.RezSingleAttachment; + client.OnDetachAttachmentIntoInv += m_innerScene.DetachSingleAttachmentToInv; client.OnObjectAttach += m_innerScene.AttachObject; client.OnObjectDetach += m_innerScene.DetachObject; client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest; diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 2493ed824e..ba318a8eca 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -663,9 +663,11 @@ namespace OpenSim.Region.Environment.Scenes { m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); m_rootPart.PhysActor = null; - AbsolutePosition = AttachOffset; - m_rootPart.m_attachedPos = AttachOffset; + } + + AbsolutePosition = AttachOffset; + m_rootPart.m_attachedPos = AttachOffset; m_rootPart.m_IsAttachment = true; m_rootPart.SetParentLocalId(avatar.LocalId); @@ -702,6 +704,26 @@ namespace OpenSim.Region.Environment.Scenes AttachToBackup(); m_rootPart.ScheduleFullUpdate(); } + public void DetachToInventoryPrep() + { + ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.m_attachedAvatar); + //LLVector3 detachedpos = new LLVector3(127f, 127f, 127f); + if (avatar != null) + { + //detachedpos = avatar.AbsolutePosition; + avatar.RemoveAttachment(this); + } + + m_rootPart.m_attachedAvatar = LLUUID.Zero; + m_rootPart.SetParentLocalId(0); + //m_rootPart.SetAttachmentPoint((byte)0); + m_rootPart.m_IsAttachment = false; + AbsolutePosition = m_rootPart.m_attachedPos; + //m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim); + //AttachToBackup(); + //m_rootPart.ScheduleFullUpdate(); + + } /// /// /// diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 08496987bb..74e9cdcfc4 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -1906,6 +1906,15 @@ namespace OpenSim.Region.Environment.Scenes internal void Close() { + lock (m_attachments) + { + foreach (SceneObjectGroup grp in m_attachments) + { + // ControllingClient may be null at this point! + m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); + } + m_attachments.Clear(); + } lock (m_knownPrimUUID) { m_knownPrimUUID.Clear(); @@ -1972,6 +1981,7 @@ namespace OpenSim.Region.Environment.Scenes gobj.RootPart.SetParentLocalId(0); gobj.RootPart.m_IsAttachment = false; gobj.AbsolutePosition = gobj.RootPart.m_attachedPos; + gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); } } diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 4dc13f574c..9e57da59e8 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -60,6 +60,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event SetAppearance OnSetAppearance; public event AvatarNowWearing OnAvatarNowWearing; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; + public event UUIDNameRequest OnDetachAttachmentIntoInv; public event ObjectAttach OnObjectAttach; public event ObjectDeselect OnObjectDetach; public event StartAnim OnStartAnim; diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5a5cf59c22..cf2e6940c5 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -150,22 +150,22 @@ namespace OpenSim.Region.Physics.OdePlugin _velocity = new PhysicsVector(); _position = pos; m_taintposition = pos; - if (_position.X > 257) - { - _position.X = 257; - } - if (_position.X < 0) - { - _position.X = 0; - } - if (_position.Y > 257) - { - _position.Y = 257; - } - if (_position.Y < 0) - { - _position.Y = 0; - } + //if (_position.X > 257) + //{ + //_position.X = 257; + //} + //if (_position.X < 0) + //{ + //_position.X = 0; + //} + //if (_position.Y > 257) + //{ + //_position.Y = 257; + //} + //if (_position.Y < 0) + //{ + // _position.Y = 0; + //} prim_geom = (IntPtr)0; prev_geom = (IntPtr)0;