aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs64
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-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/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs21
10 files changed, 68 insertions, 42 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 041fb94..ba6d87d 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -497,8 +497,6 @@ namespace OpenSim.Framework
497 /// </remarks> 497 /// </remarks>
498 public List<AvatarAttachment> GetAttachments() 498 public List<AvatarAttachment> GetAttachments()
499 { 499 {
500
501
502 lock (m_attachments) 500 lock (m_attachments)
503 { 501 {
504 List<AvatarAttachment> alist = new List<AvatarAttachment>(); 502 List<AvatarAttachment> alist = new List<AvatarAttachment>();
@@ -508,7 +506,8 @@ namespace OpenSim.Framework
508 alist.Add(new AvatarAttachment(attach)); 506 alist.Add(new AvatarAttachment(attach));
509 } 507 }
510 return alist; 508 return alist;
511 } } 509 }
510 }
512 511
513 internal void AppendAttachment(AvatarAttachment attach) 512 internal void AppendAttachment(AvatarAttachment attach)
514 { 513 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 165dd17..71945c5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -236,9 +236,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
236 // If we're an NPC then skip all the item checks and manipulations since we don't have an 236 // If we're an NPC then skip all the item checks and manipulations since we don't have an
237 // inventory right now. 237 // inventory right now.
238 if (sp.PresenceType == PresenceType.Npc) 238 if (sp.PresenceType == PresenceType.Npc)
239 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); 239 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true);
240 else 240 else
241 RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); 241 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d);
242 } 242 }
243 catch (Exception e) 243 catch (Exception e)
244 { 244 {
@@ -299,12 +299,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
299 sp.ClearAttachments(); 299 sp.ClearAttachments();
300 } 300 }
301 301
302 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) 302 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append)
303 { 303 {
304 if (!Enabled) 304 if (!Enabled)
305 return false; 305 return false;
306 306
307 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp)) 307 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, append))
308 { 308 {
309 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); 309 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
310 return true; 310 return true;
@@ -313,7 +313,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
313 return false; 313 return false;
314 } 314 }
315 315
316 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) 316 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append)
317 { 317 {
318// m_log.DebugFormat( 318// m_log.DebugFormat(
319// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", 319// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
@@ -348,11 +348,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
348 lock (sp.AttachmentsSyncLock) 348 lock (sp.AttachmentsSyncLock)
349 { 349 {
350 Vector3 attachPos = group.AbsolutePosition; 350 Vector3 attachPos = group.AbsolutePosition;
351 351
352 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
353 // be removed when that functionality is implemented in opensim
354 attachmentPt &= 0x7f;
355
356 // If the attachment point isn't the same as the one previously used 352 // If the attachment point isn't the same as the one previously used
357 // set it's offset position = 0 so that it appears on the attachment point 353 // set it's offset position = 0 so that it appears on the attachment point
358 // and not in a weird location somewhere unknown. 354 // and not in a weird location somewhere unknown.
@@ -398,15 +394,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
398 group.AbsolutePosition = attachPos; 394 group.AbsolutePosition = attachPos;
399 395
400 if (sp.PresenceType != PresenceType.Npc) 396 if (sp.PresenceType != PresenceType.Npc)
401 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 397 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
402 398
403 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 399 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
404 } 400 }
405 401
406 return true; 402 return true;
407 } 403 }
408 404
409 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 405 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
410 { 406 {
411 // Add the new attachment to inventory if we don't already have it. 407 // Add the new attachment to inventory if we don't already have it.
412 if (!temp) 408 if (!temp)
@@ -415,7 +411,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
415 if (newAttachmentItemID == UUID.Zero) 411 if (newAttachmentItemID == UUID.Zero)
416 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 412 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
417 413
418 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 414 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
419 } 415 }
420 } 416 }
421 417
@@ -433,8 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
433// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 429// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
434// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 430// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
435 431
436 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 432 bool append = (AttachmentPt & 0x80) != 0;
437 // be removed when that functionality is implemented in opensim
438 AttachmentPt &= 0x7f; 433 AttachmentPt &= 0x7f;
439 434
440 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 435 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
@@ -463,7 +458,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
463 return null; 458 return null;
464 } 459 }
465 460
466 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); 461 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append);
467 } 462 }
468 463
469 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 464 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -860,7 +855,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
860 } 855 }
861 856
862 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 857 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
863 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) 858 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append)
864 { 859 {
865 if (m_invAccessModule == null) 860 if (m_invAccessModule == null)
866 return null; 861 return null;
@@ -885,13 +880,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
885 return null; 880 return null;
886 } 881 }
887 882
888 // Remove any previous attachments
889 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 883 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
890 string previousAttachmentScriptedState = null; 884 string previousAttachmentScriptedState = null;
891 885
892 // At the moment we can only deal with a single attachment 886 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
893 if (attachments.Count != 0) 887 while (attachments.Count >= 5)
894 DetachSingleAttachmentToInv(sp, attachments[0]); 888 {
889 if (attachments[0].FromItemID != UUID.Zero)
890 DetachSingleAttachmentToInv(sp, attachments[0]);
891 attachments.RemoveAt(0);
892 }
893
894 // If we're not appending, remove the rest as well
895 if (attachments.Count != 0 && !append)
896 {
897 foreach (SceneObjectGroup g in attachments)
898 {
899 if (g.FromItemID != UUID.Zero)
900 DetachSingleAttachmentToInv(sp, g);
901 }
902 }
895 903
896 lock (sp.AttachmentsSyncLock) 904 lock (sp.AttachmentsSyncLock)
897 { 905 {
@@ -913,7 +921,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
913 // This will throw if the attachment fails 921 // This will throw if the attachment fails
914 try 922 try
915 { 923 {
916 AttachObjectInternal(sp, objatt, attachmentPt, false, false, false); 924 AttachObjectInternal(sp, objatt, attachmentPt, false, false, false, append);
917 } 925 }
918 catch (Exception e) 926 catch (Exception e)
919 { 927 {
@@ -955,7 +963,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
955 /// <param name="AttachmentPt"></param> 963 /// <param name="AttachmentPt"></param>
956 /// <param name="itemID"></param> 964 /// <param name="itemID"></param>
957 /// <param name="att"></param> 965 /// <param name="att"></param>
958 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 966 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
959 { 967 {
960// m_log.DebugFormat( 968// m_log.DebugFormat(
961// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 969// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -978,7 +986,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
978 if (item == null) 986 if (item == null)
979 return; 987 return;
980 988
981 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 989 int attFlag = append ? 0x80 : 0;
990 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
982 if (changed && m_scene.AvatarFactory != null) 991 if (changed && m_scene.AvatarFactory != null)
983 { 992 {
984// m_log.DebugFormat( 993// m_log.DebugFormat(
@@ -1062,12 +1071,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1062 return; 1071 return;
1063 } 1072 }
1064 1073
1065 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 1074 bool append = (AttachmentPt & 0x80) != 0;
1066 // be removed when that functionality is implemented in opensim
1067 AttachmentPt &= 0x7f; 1075 AttachmentPt &= 0x7f;
1068 1076
1069 // Calls attach with a Zero position 1077 // Calls attach with a Zero position
1070 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false)) 1078 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false, append))
1071 { 1079 {
1072// m_log.Debug( 1080// m_log.Debug(
1073// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 1081// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 4e9d3f9..545aeda 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, false); 200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, 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, false); 257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, 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));
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 6bf50d2..fccf053 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -262,6 +262,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
262 return "modInvokeR"; 262 return "modInvokeR";
263 else if (sid.ReturnType == typeof(object[])) 263 else if (sid.ReturnType == typeof(object[]))
264 return "modInvokeL"; 264 return "modInvokeL";
265 else if (sid.ReturnType == typeof(void))
266 return "modInvokeN";
265 267
266 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); 268 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
267 } 269 }
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index d781eae..eaaf7a3 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Interfaces
84 /// <param name="AttachmentPt"></param> 84 /// <param name="AttachmentPt"></param>
85 /// <param name="silent"></param> 85 /// <param name="silent"></param>
86 /// <returns>true if the object was successfully attached, false otherwise</returns> 86 /// <returns>true if the object was successfully attached, false otherwise</returns>
87 bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp); 87 bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp, bool append);
88 88
89 /// <summary> 89 /// <summary>
90 /// Rez an attachment from user inventory and change inventory status to match. 90 /// 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 d459b56..92d0aff 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2863,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
2863 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2863 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2864 2864
2865 if (AttachmentsModule != null) 2865 if (AttachmentsModule != null)
2866 AttachmentsModule.AttachObject(sp, grp, 0, false, false, false); 2866 AttachmentsModule.AttachObject(sp, grp, 0, false, false, false, true);
2867 } 2867 }
2868 else 2868 else
2869 { 2869 {
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
index e9ddbbe..bed192a 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, true) ? 1 : 0; 186 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, 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 29476b9..4a24d22 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3306,7 +3306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3306 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3306 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3307 3307
3308 if (attachmentsModule != null) 3308 if (attachmentsModule != null)
3309 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false); 3309 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3310 else 3310 else
3311 return false; 3311 return false;
3312 } 3312 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index d0922aa..542222e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -325,6 +325,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
325 if (result != null) 325 if (result != null)
326 return result; 326 return result;
327 327
328 Type returntype = m_comms.LookupReturnType(fname);
329 if (returntype == typeof(void))
330 return null;
331
328 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 332 MODError(String.Format("Invocation of {0} failed; null return value",fname));
329 } 333 }
330 catch (Exception e) 334 catch (Exception e)
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index c0130f1..3663a7a 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -180,11 +180,18 @@ namespace OpenSim.Services.Interfaces
180 180
181 // Attachments 181 // Attachments
182 List<AvatarAttachment> attachments = appearance.GetAttachments(); 182 List<AvatarAttachment> attachments = appearance.GetAttachments();
183 Dictionary<int, List<string>> atts = new Dictionary<int, List<string>>();
183 foreach (AvatarAttachment attach in attachments) 184 foreach (AvatarAttachment attach in attachments)
184 { 185 {
185 if (attach.ItemID != UUID.Zero) 186 if (attach.ItemID != UUID.Zero)
186 Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString(); 187 {
188 if (!atts.ContainsKey(attach.AttachPoint))
189 atts[attach.AttachPoint] = new List<string>();
190 atts[attach.AttachPoint].Add(attach.ItemID.ToString());
191 }
187 } 192 }
193 foreach (KeyValuePair<int, List<string>> kvp in atts)
194 Data["_ap_" + kvp.Key] = string.Join(",", kvp.Value.ToArray());
188 } 195 }
189 196
190 public AvatarAppearance ToAvatarAppearance() 197 public AvatarAppearance ToAvatarAppearance()
@@ -320,10 +327,16 @@ namespace OpenSim.Services.Interfaces
320 if (!Int32.TryParse(pointStr, out point)) 327 if (!Int32.TryParse(pointStr, out point))
321 continue; 328 continue;
322 329
323 UUID uuid = UUID.Zero; 330 List<string> idList = new List<string>(_kvp.Value.Split(new char[] {','}));
324 UUID.TryParse(_kvp.Value, out uuid);
325 331
326 appearance.SetAttachment(point, uuid, UUID.Zero); 332 appearance.SetAttachment(point, UUID.Zero, UUID.Zero);
333 foreach (string id in idList)
334 {
335 UUID uuid = UUID.Zero;
336 UUID.TryParse(id, out uuid);
337
338 appearance.SetAttachment(point | 0x80, uuid, UUID.Zero);
339 }
327 } 340 }
328 341
329 if (appearance.Wearables[AvatarWearable.BODY].Count == 0) 342 if (appearance.Wearables[AvatarWearable.BODY].Count == 0)