aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs133
-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.cs2
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs21
7 files changed, 97 insertions, 71 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 1c28f49..2dea14d 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 {
@@ -283,13 +283,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
283 283
284 sp.ClearAttachments(); 284 sp.ClearAttachments();
285 } 285 }
286 286
287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
288 { 288 {
289 if (!Enabled) 289 if (!Enabled)
290 return false; 290 return false;
291 291
292 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, false); 292 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, append);
293 } 293 }
294 294
295 /// <summary> 295 /// <summary>
@@ -305,19 +305,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
305 private bool AttachObjectInternal( 305 private bool AttachObjectInternal(
306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) 306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts)
307 { 307 {
308 if (sp.GetAttachments().Contains(group))
309 {
310// m_log.WarnFormat(
311// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
312// group.Name, group.LocalId, sp.Name, AttachmentPt);
313
314 return false;
315 }
316
317// m_log.DebugFormat(
318// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
319// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
320
321 if (group.GetSittingAvatarsCount() != 0) 308 if (group.GetSittingAvatarsCount() != 0)
322 { 309 {
323// m_log.WarnFormat( 310// m_log.WarnFormat(
@@ -327,50 +314,67 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
327 return false; 314 return false;
328 } 315 }
329 316
330 Vector3 attachPos = group.AbsolutePosition; 317 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
331 318
332 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 319 if (attachments.Contains(group))
333 // be removed when that functionality is implemented in opensim
334 attachmentPt &= 0x7f;
335
336 // If the attachment point isn't the same as the one previously used
337 // set it's offset position = 0 so that it appears on the attachment point
338 // and not in a weird location somewhere unknown.
339 if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
340 { 320 {
341 attachPos = Vector3.Zero; 321// m_log.WarnFormat(
322// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
323// group.Name, group.LocalId, sp.Name, AttachmentPt);
324
325 return false;
342 } 326 }
343 327
344 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. 328 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
345 if (attachmentPt == (uint)AttachmentPoint.Default) 329 while (attachments.Count >= 5)
346 { 330 {
347 // Check object for stored attachment point 331 if (attachments[0].FromItemID != UUID.Zero)
348 attachmentPt = group.AttachmentPoint; 332 DetachSingleAttachmentToInv(sp, attachments[0]);
333 attachments.RemoveAt(0);
349 } 334 }
350 335
351 // if we still didn't find a suitable attachment point....... 336 // If we're not appending, remove the rest as well
352 if (attachmentPt == 0) 337 if (attachments.Count != 0 && !append)
353 { 338 {
354 // Stick it on left hand with Zero Offset from the attachment point. 339 foreach (SceneObjectGroup g in attachments)
355 attachmentPt = (uint)AttachmentPoint.LeftHand; 340 {
356 attachPos = Vector3.Zero; 341 if (g.FromItemID != UUID.Zero)
342 DetachSingleAttachmentToInv(sp, g);
343 }
357 } 344 }
358 345
359 // Remove any previous attachments
360 List<SceneObjectGroup> existingAttachments = sp.GetAttachments(attachmentPt);
361
362 // At the moment we can only deal with a single attachment
363 if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero)
364 DetachSingleAttachmentToInv(sp, existingAttachments[0]);
365
366 lock (sp.AttachmentsSyncLock) 346 lock (sp.AttachmentsSyncLock)
367 { 347 {
348 Vector3 attachPos = group.AbsolutePosition;
349 // If the attachment point isn't the same as the one previously used
350 // set it's offset position = 0 so that it appears on the attachment point
351 // and not in a weird location somewhere unknown.
352 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
353 {
354 attachPos = Vector3.Zero;
355 }
356
357 // AttachmentPt 0 means the client chose to 'wear' the attachment.
358 if (attachmentPt == 0)
359 {
360 // Check object for stored attachment point
361 attachmentPt = group.AttachmentPoint;
362 }
363
364 // if we still didn't find a suitable attachment point.......
365 if (attachmentPt == 0)
366 {
367 // Stick it on left hand with Zero Offset from the attachment point.
368 attachmentPt = (uint)AttachmentPoint.LeftHand;
369 attachPos = Vector3.Zero;
370 }
371
368 group.AttachmentPoint = attachmentPt; 372 group.AttachmentPoint = attachmentPt;
369 group.AbsolutePosition = attachPos; 373 group.AbsolutePosition = attachPos;
370 374
371 if (sp.PresenceType != PresenceType.Npc) 375 if (sp.PresenceType != PresenceType.Npc)
372 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 376 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
373 377
374 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 378 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
375 379
376 if (resumeScripts) 380 if (resumeScripts)
@@ -388,8 +392,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
388 return true; 392 return true;
389 } 393 }
390 394
391 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 395 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
392 { 396 {
397 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
398
393 // Add the new attachment to inventory if we don't already have it. 399 // Add the new attachment to inventory if we don't already have it.
394 if (!temp) 400 if (!temp)
395 { 401 {
@@ -397,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
397 if (newAttachmentItemID == UUID.Zero) 403 if (newAttachmentItemID == UUID.Zero)
398 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 404 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
399 405
400 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 406 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
401 } 407 }
402 } 408 }
403 409
@@ -410,8 +416,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
410// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", 416// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
411// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); 417// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
412 418
413 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 419 bool append = (AttachmentPt & 0x80) != 0;
414 // be removed when that functionality is implemented in opensim
415 AttachmentPt &= 0x7f; 420 AttachmentPt &= 0x7f;
416 421
417 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 422 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
@@ -440,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
440 return null; 445 return null;
441 } 446 }
442 447
443 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 448 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append);
444 } 449 }
445 450
446 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 451 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -840,8 +845,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
840 so.RemoveScriptInstances(true); 845 so.RemoveScriptInstances(true);
841 } 846 }
842 847
843 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 848 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
844 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 849 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append)
845 { 850 {
846 if (m_invAccessModule == null) 851 if (m_invAccessModule == null)
847 return null; 852 return null;
@@ -884,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
884 // This will throw if the attachment fails 889 // This will throw if the attachment fails
885 try 890 try
886 { 891 {
887 AttachObjectInternal(sp, objatt, attachmentPt, false, false, true); 892 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append);
888 } 893 }
889 catch (Exception e) 894 catch (Exception e)
890 { 895 {
@@ -911,7 +916,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
911 /// <param name="AttachmentPt"></param> 916 /// <param name="AttachmentPt"></param>
912 /// <param name="itemID"></param> 917 /// <param name="itemID"></param>
913 /// <param name="att"></param> 918 /// <param name="att"></param>
914 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 919 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
915 { 920 {
916// m_log.DebugFormat( 921// m_log.DebugFormat(
917// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 922// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -934,7 +939,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
934 if (item == null) 939 if (item == null)
935 return; 940 return;
936 941
937 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 942 int attFlag = append ? 0x80 : 0;
943 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
938 if (changed && m_scene.AvatarFactory != null) 944 if (changed && m_scene.AvatarFactory != null)
939 { 945 {
940// m_log.DebugFormat( 946// m_log.DebugFormat(
@@ -1018,12 +1024,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1018 return; 1024 return;
1019 } 1025 }
1020 1026
1021 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 1027 bool append = (AttachmentPt & 0x80) != 0;
1022 // be removed when that functionality is implemented in opensim
1023 AttachmentPt &= 0x7f; 1028 AttachmentPt &= 0x7f;
1024 1029
1025 // Calls attach with a Zero position 1030 // Calls attach with a Zero position
1026 AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); 1031 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append))
1032 {
1033// m_log.Debug(
1034// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1035// + ", AttachmentPoint: " + AttachmentPt);
1036
1037 // Save avatar attachment information
1038 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
1039 }
1027 } 1040 }
1028 catch (Exception e) 1041 catch (Exception e)
1029 { 1042 {
@@ -1076,4 +1089,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1076 1089
1077 #endregion 1090 #endregion
1078 } 1091 }
1079} \ No newline at end of file 1092}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 719a59c..0c1df6a 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);
@@ -368,7 +368,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
368 sp2.AbsolutePosition = new Vector3(0, 0, 0); 368 sp2.AbsolutePosition = new Vector3(0, 0, 0);
369 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 369 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
370 370
371 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); 371 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
372 372
373 Assert.That(sp.HasAttachments(), Is.False); 373 Assert.That(sp.HasAttachments(), Is.False);
374 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 374 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -888,4 +888,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
888 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); 888 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
889 } 889 }
890 } 890 }
891} \ No newline at end of file 891}
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 f07b645..e1f0071 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3063,7 +3063,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3063 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3063 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3064 3064
3065 if (attachmentsModule != null) 3065 if (attachmentsModule != null)
3066 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3066 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true);
3067 else 3067 else
3068 return false; 3068 return false;
3069 } 3069 }
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index 863fd93..6ca0b15 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()
@@ -304,10 +311,16 @@ namespace OpenSim.Services.Interfaces
304 if (!Int32.TryParse(pointStr, out point)) 311 if (!Int32.TryParse(pointStr, out point))
305 continue; 312 continue;
306 313
307 UUID uuid = UUID.Zero; 314 List<string> idList = new List<string>(_kvp.Value.Split(new char[] {','}));
308 UUID.TryParse(_kvp.Value, out uuid);
309 315
310 appearance.SetAttachment(point, uuid, UUID.Zero); 316 appearance.SetAttachment(point, UUID.Zero, UUID.Zero);
317 foreach (string id in idList)
318 {
319 UUID uuid = UUID.Zero;
320 UUID.TryParse(id, out uuid);
321
322 appearance.SetAttachment(point | 0x80, uuid, UUID.Zero);
323 }
311 } 324 }
312 325
313 if (appearance.Wearables[AvatarWearable.BODY].Count == 0) 326 if (appearance.Wearables[AvatarWearable.BODY].Count == 0)