aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs58
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs6
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs4
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs9
7 files changed, 44 insertions, 39 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 8a3eeaa..f8fc483 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -221,9 +221,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
221 // If we're an NPC then skip all the item checks and manipulations since we don't have an 221 // If we're an NPC then skip all the item checks and manipulations since we don't have an
222 // inventory right now. 222 // inventory right now.
223 if (sp.PresenceType == PresenceType.Npc) 223 if (sp.PresenceType == PresenceType.Npc)
224 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); 224 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true);
225 else 225 else
226 RezSingleAttachmentFromInventory(sp, attach.ItemID, p); 226 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80);
227 } 227 }
228 catch (Exception e) 228 catch (Exception e)
229 { 229 {
@@ -268,13 +268,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
268 268
269 sp.ClearAttachments(); 269 sp.ClearAttachments();
270 } 270 }
271 271
272 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 272 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
273 { 273 {
274 if (!Enabled) 274 if (!Enabled)
275 return false; 275 return false;
276 276
277 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) 277 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp, append))
278 { 278 {
279 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); 279 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
280 return true; 280 return true;
@@ -283,7 +283,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
283 return false; 283 return false;
284 } 284 }
285 285
286 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 286 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
287 { 287 {
288 lock (sp.AttachmentsSyncLock) 288 lock (sp.AttachmentsSyncLock)
289 { 289 {
@@ -311,10 +311,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
311 311
312 Vector3 attachPos = group.AbsolutePosition; 312 Vector3 attachPos = group.AbsolutePosition;
313 313
314 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
315 // be removed when that functionality is implemented in opensim
316 attachmentPt &= 0x7f;
317
318 // If the attachment point isn't the same as the one previously used 314 // If the attachment point isn't the same as the one previously used
319 // set it's offset position = 0 so that it appears on the attachment point 315 // set it's offset position = 0 so that it appears on the attachment point
320 // and not in a weird location somewhere unknown. 316 // and not in a weird location somewhere unknown.
@@ -342,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
342 group.AbsolutePosition = attachPos; 338 group.AbsolutePosition = attachPos;
343 339
344 if (sp.PresenceType != PresenceType.Npc) 340 if (sp.PresenceType != PresenceType.Npc)
345 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 341 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
346 342
347 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 343 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
348 } 344 }
@@ -350,21 +346,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
350 return true; 346 return true;
351 } 347 }
352 348
353 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 349 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
354 { 350 {
355 // Remove any previous attachments 351 // Remove any previous attachments
356 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 352 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
357 353
358 // At the moment we can only deal with a single attachment 354 // At the moment we can only deal with a single attachment
359 if (attachments.Count != 0) 355 if (attachments.Count != 0 && !append)
360 { 356 {
361 if (attachments[0].FromItemID != UUID.Zero) 357 if (attachments[0].FromItemID != UUID.Zero)
362 DetachSingleAttachmentToInvInternal(sp, attachments[0]); 358 DetachSingleAttachmentToInvInternal(sp, attachments[0]);
363 // Error logging commented because UUID.Zero now means temp attachment
364// else
365// m_log.WarnFormat(
366// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
367// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
368 } 359 }
369 360
370 // Add the new attachment to inventory if we don't already have it. 361 // Add the new attachment to inventory if we don't already have it.
@@ -374,7 +365,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
374 if (newAttachmentItemID == UUID.Zero) 365 if (newAttachmentItemID == UUID.Zero)
375 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 366 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
376 367
377 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 368 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
378 } 369 }
379 } 370 }
380 371
@@ -387,8 +378,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
387// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 378// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
388// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 379// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
389 380
390 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 381 bool append = (AttachmentPt & 0x80) != 0;
391 // be removed when that functionality is implemented in opensim
392 AttachmentPt &= 0x7f; 382 AttachmentPt &= 0x7f;
393 383
394 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 384 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
@@ -417,7 +407,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
417 return null; 407 return null;
418 } 408 }
419 409
420 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 410 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append);
421 } 411 }
422 412
423 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 413 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -803,8 +793,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
803 UpdateDetachedObject(sp, so); 793 UpdateDetachedObject(sp, so);
804 } 794 }
805 795
806 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 796 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
807 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 797 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append)
808 { 798 {
809 if (m_invAccessModule == null) 799 if (m_invAccessModule == null)
810 return null; 800 return null;
@@ -842,7 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
842 // This will throw if the attachment fails 832 // This will throw if the attachment fails
843 try 833 try
844 { 834 {
845 AttachObjectInternal(sp, objatt, attachmentPt, false, false); 835 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append);
846 } 836 }
847 catch (Exception e) 837 catch (Exception e)
848 { 838 {
@@ -887,7 +877,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
887 /// <param name="AttachmentPt"></param> 877 /// <param name="AttachmentPt"></param>
888 /// <param name="itemID"></param> 878 /// <param name="itemID"></param>
889 /// <param name="att"></param> 879 /// <param name="att"></param>
890 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 880 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
891 { 881 {
892// m_log.DebugFormat( 882// m_log.DebugFormat(
893// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 883// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -910,7 +900,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
910 if (item == null) 900 if (item == null)
911 return; 901 return;
912 902
913 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 903 int attFlag = append ? 0x80 : 0;
904 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
914 if (changed && m_scene.AvatarFactory != null) 905 if (changed && m_scene.AvatarFactory != null)
915 { 906 {
916// m_log.DebugFormat( 907// m_log.DebugFormat(
@@ -994,12 +985,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
994 return; 985 return;
995 } 986 }
996 987
997 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 988 bool append = (AttachmentPt & 0x80) != 0;
998 // be removed when that functionality is implemented in opensim
999 AttachmentPt &= 0x7f; 989 AttachmentPt &= 0x7f;
1000 990
1001 // Calls attach with a Zero position 991 // Calls attach with a Zero position
1002 AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); 992 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append))
993 {
994// m_log.Debug(
995// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
996// + ", AttachmentPoint: " + AttachmentPt);
997
998 // Save avatar attachment information
999 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
1000 }
1003 } 1001 }
1004 catch (Exception e) 1002 catch (Exception e)
1005 { 1003 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 0ee01c7..f48bb6f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
198 198
199 m_numberOfAttachEventsFired = 0; 199 m_numberOfAttachEventsFired = 0;
200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); 200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
201 201
202 // Check status on scene presence 202 // Check status on scene presence
203 Assert.That(sp.HasAttachments(), Is.True); 203 Assert.That(sp.HasAttachments(), Is.True);
@@ -254,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
254 sp2.AbsolutePosition = new Vector3(0, 0, 0); 254 sp2.AbsolutePosition = new Vector3(0, 0, 0);
255 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 255 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
256 256
257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); 257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
258 258
259 Assert.That(sp.HasAttachments(), Is.False); 259 Assert.That(sp.HasAttachments(), Is.False);
260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -663,4 +663,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
663 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); 663 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
664 } 664 }
665 } 665 }
666} \ No newline at end of file 666}
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 620ec22..46daab3 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.Framework.Interfaces
83 /// <param name="AttachmentPt"></param> 83 /// <param name="AttachmentPt"></param>
84 /// <param name="silent"></param> 84 /// <param name="silent"></param>
85 /// <returns>true if the object was successfully attached, false otherwise</returns> 85 /// <returns>true if the object was successfully attached, false otherwise</returns>
86 bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp); 86 bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool temp, bool append);
87 87
88 /// <summary> 88 /// <summary>
89 /// Rez an attachment from user inventory and change inventory status to match. 89 /// Rez an attachment from user inventory and change inventory status to match.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 14dac7a..3c91c5b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2741,7 +2741,7 @@ namespace OpenSim.Region.Framework.Scenes
2741 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2741 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2742 2742
2743 if (AttachmentsModule != null) 2743 if (AttachmentsModule != null)
2744 AttachmentsModule.AttachObject(sp, grp, 0, false, false); 2744 AttachmentsModule.AttachObject(sp, grp, 0, false, false, true);
2745 } 2745 }
2746 else 2746 else
2747 { 2747 {
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
index 1e7bc02..e9ddbbe 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
@@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
183 hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); 183 hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
184 } 184 }
185 185
186 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0; 186 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0;
187 } 187 }
188 } 188 }
189} 189}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ab087af..cf6f13e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2985,7 +2985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2985 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 2985 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2986 2986
2987 if (attachmentsModule != null) 2987 if (attachmentsModule != null)
2988 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 2988 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true);
2989 else 2989 else
2990 return false; 2990 return false;
2991 } 2991 }
@@ -11787,4 +11787,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11787 } 11787 }
11788 } 11788 }
11789 } 11789 }
11790} \ No newline at end of file 11790}
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index 863fd93..606e82c 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -174,11 +174,18 @@ namespace OpenSim.Services.Interfaces
174 174
175 // Attachments 175 // Attachments
176 List<AvatarAttachment> attachments = appearance.GetAttachments(); 176 List<AvatarAttachment> attachments = appearance.GetAttachments();
177 Dictionary<int, List<string>> atts = new Dictionary<int, List<string>>();
177 foreach (AvatarAttachment attach in attachments) 178 foreach (AvatarAttachment attach in attachments)
178 { 179 {
179 if (attach.ItemID != UUID.Zero) 180 if (attach.ItemID != UUID.Zero)
180 Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString(); 181 {
182 if (!atts.ContainsKey(attach.AttachPoint))
183 atts[attach.AttachPoint] = new List<string>();
184 atts[attach.AttachPoint].Add(attach.ItemID.ToString());
185 }
181 } 186 }
187 foreach (KeyValuePair<int, List<string>> kvp in atts)
188 Data["_ap_" + kvp.Key] = string.Join(",", kvp.Value.ToArray());
182 } 189 }
183 190
184 public AvatarAppearance ToAvatarAppearance() 191 public AvatarAppearance ToAvatarAppearance()