diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index f69ec21..0f03ad0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework; | |||
40 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.Framework.Scenes.Serialization; | 42 | using OpenSim.Region.Framework.Scenes.Serialization; |
43 | using OpenSim.Services.Interfaces; | ||
43 | 44 | ||
44 | namespace OpenSim.Region.CoreModules.Avatar.Attachments | 45 | namespace OpenSim.Region.CoreModules.Avatar.Attachments |
45 | { | 46 | { |
@@ -235,6 +236,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
235 | if (DebugLevel > 0) | 236 | if (DebugLevel > 0) |
236 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); | 237 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); |
237 | 238 | ||
239 | XmlDocument doc = new XmlDocument(); | ||
240 | string stateData = String.Empty; | ||
241 | |||
242 | IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>(); | ||
243 | if (attServ != null) | ||
244 | { | ||
245 | m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); | ||
246 | stateData = attServ.Get(sp.UUID.ToString()); | ||
247 | if (stateData != String.Empty) | ||
248 | { | ||
249 | try | ||
250 | { | ||
251 | doc.LoadXml(stateData); | ||
252 | } | ||
253 | catch { } | ||
254 | } | ||
255 | } | ||
256 | |||
257 | Dictionary<UUID, string> itemData = new Dictionary<UUID, string>(); | ||
258 | |||
259 | XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); | ||
260 | if (nodes.Count > 0) | ||
261 | { | ||
262 | foreach (XmlNode n in nodes) | ||
263 | { | ||
264 | XmlElement elem = (XmlElement)n; | ||
265 | string itemID = elem.GetAttribute("ItemID"); | ||
266 | string xml = elem.InnerXml; | ||
267 | |||
268 | itemData[new UUID(itemID)] = xml; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | |||
238 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 273 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); |
239 | foreach (AvatarAttachment attach in attachments) | 274 | foreach (AvatarAttachment attach in attachments) |
240 | { | 275 | { |
@@ -254,10 +289,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
254 | 289 | ||
255 | try | 290 | try |
256 | { | 291 | { |
292 | string xmlData; | ||
293 | XmlDocument d = null; | ||
294 | UUID asset; | ||
295 | if (itemData.TryGetValue(attach.ItemID, out xmlData)) | ||
296 | { | ||
297 | d = new XmlDocument(); | ||
298 | d.LoadXml(xmlData); | ||
299 | m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID); | ||
300 | } | ||
301 | |||
257 | // If we're an NPC then skip all the item checks and manipulations since we don't have an | 302 | // If we're an NPC then skip all the item checks and manipulations since we don't have an |
258 | // inventory right now. | 303 | // inventory right now. |
259 | RezSingleAttachmentFromInventoryInternal( | 304 | RezSingleAttachmentFromInventoryInternal( |
260 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true); | 305 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null); |
261 | } | 306 | } |
262 | catch (Exception e) | 307 | catch (Exception e) |
263 | { | 308 | { |
@@ -320,13 +365,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
320 | sp.ClearAttachments(); | 365 | sp.ClearAttachments(); |
321 | } | 366 | } |
322 | 367 | ||
323 | public bool AttachObject( | 368 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append) |
324 | IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append) | ||
325 | { | 369 | { |
326 | if (!Enabled) | 370 | if (!Enabled) |
327 | return false; | 371 | return false; |
328 | 372 | ||
329 | return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); | 373 | return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append); |
330 | } | 374 | } |
331 | 375 | ||
332 | /// <summary> | 376 | /// <summary> |
@@ -339,10 +383,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
339 | /// <param name='silent'></param> | 383 | /// <param name='silent'></param> |
340 | /// <param name='addToInventory'>If true then add object to user inventory.</param> | 384 | /// <param name='addToInventory'>If true then add object to user inventory.</param> |
341 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> | 385 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> |
342 | /// <param name='append'>Append to attachment point rather than replace.</param> | 386 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append) |
343 | private bool AttachObjectInternal( | ||
344 | IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append) | ||
345 | { | 387 | { |
388 | // m_log.DebugFormat( | ||
389 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | ||
390 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | ||
391 | |||
392 | if (sp.GetAttachments().Contains(group)) | ||
393 | { | ||
394 | // m_log.WarnFormat( | ||
395 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
396 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | ||
397 | |||
398 | return false; | ||
399 | } | ||
400 | |||
346 | if (group.GetSittingAvatarsCount() != 0) | 401 | if (group.GetSittingAvatarsCount() != 0) |
347 | { | 402 | { |
348 | if (DebugLevel > 0) | 403 | if (DebugLevel > 0) |
@@ -354,6 +409,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
354 | } | 409 | } |
355 | 410 | ||
356 | Vector3 attachPos = group.AbsolutePosition; | 411 | Vector3 attachPos = group.AbsolutePosition; |
412 | |||
413 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | ||
414 | // be removed when that functionality is implemented in opensim | ||
415 | attachmentPt &= 0x7f; | ||
416 | |||
357 | // If the attachment point isn't the same as the one previously used | 417 | // If the attachment point isn't the same as the one previously used |
358 | // set it's offset position = 0 so that it appears on the attachment point | 418 | // set it's offset position = 0 so that it appears on the attachment point |
359 | // and not in a weird location somewhere unknown. | 419 | // and not in a weird location somewhere unknown. |
@@ -362,7 +422,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
362 | attachPos = Vector3.Zero; | 422 | attachPos = Vector3.Zero; |
363 | } | 423 | } |
364 | 424 | ||
365 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | 425 | // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. |
366 | if (attachmentPt == (uint)AttachmentPoint.Default) | 426 | if (attachmentPt == (uint)AttachmentPoint.Default) |
367 | { | 427 | { |
368 | // Check object for stored attachment point | 428 | // Check object for stored attachment point |
@@ -377,9 +437,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
377 | attachPos = Vector3.Zero; | 437 | attachPos = Vector3.Zero; |
378 | } | 438 | } |
379 | 439 | ||
380 | group.AttachmentPoint = attachmentPt; | ||
381 | group.AbsolutePosition = attachPos; | ||
382 | |||
383 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 440 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); |
384 | 441 | ||
385 | if (attachments.Contains(group)) | 442 | if (attachments.Contains(group)) |
@@ -412,6 +469,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
412 | 469 | ||
413 | lock (sp.AttachmentsSyncLock) | 470 | lock (sp.AttachmentsSyncLock) |
414 | { | 471 | { |
472 | group.AttachmentPoint = attachmentPt; | ||
473 | group.AbsolutePosition = attachPos; | ||
474 | |||
415 | if (addToInventory && sp.PresenceType != PresenceType.Npc) | 475 | if (addToInventory && sp.PresenceType != PresenceType.Npc) |
416 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); | 476 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); |
417 | 477 | ||
@@ -442,7 +502,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
442 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); | 502 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); |
443 | } | 503 | } |
444 | 504 | ||
445 | public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 505 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
506 | { | ||
507 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); | ||
508 | } | ||
509 | |||
510 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) | ||
446 | { | 511 | { |
447 | if (!Enabled) | 512 | if (!Enabled) |
448 | return null; | 513 | return null; |
@@ -480,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
480 | bool append = (AttachmentPt & 0x80) != 0; | 545 | bool append = (AttachmentPt & 0x80) != 0; |
481 | AttachmentPt &= 0x7f; | 546 | AttachmentPt &= 0x7f; |
482 | 547 | ||
483 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); | 548 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc); |
484 | } | 549 | } |
485 | 550 | ||
486 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 551 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -557,7 +622,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
557 | so.AttachedAvatar = UUID.Zero; | 622 | so.AttachedAvatar = UUID.Zero; |
558 | rootPart.SetParentLocalId(0); | 623 | rootPart.SetParentLocalId(0); |
559 | so.ClearPartAttachmentData(); | 624 | so.ClearPartAttachmentData(); |
560 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); | 625 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false); |
561 | so.HasGroupChanged = true; | 626 | so.HasGroupChanged = true; |
562 | rootPart.Rezzed = DateTime.Now; | 627 | rootPart.Rezzed = DateTime.Now; |
563 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); | 628 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); |
@@ -890,7 +955,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
890 | } | 955 | } |
891 | 956 | ||
892 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 957 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
893 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) | 958 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc) |
894 | { | 959 | { |
895 | if (m_invAccessModule == null) | 960 | if (m_invAccessModule == null) |
896 | return null; | 961 | return null; |
@@ -934,7 +999,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
934 | // This will throw if the attachment fails | 999 | // This will throw if the attachment fails |
935 | try | 1000 | try |
936 | { | 1001 | { |
937 | AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); | 1002 | if (doc != null) |
1003 | { | ||
1004 | objatt.LoadScriptState(doc); | ||
1005 | objatt.ResetOwnerChangeFlag(); | ||
1006 | } | ||
1007 | |||
1008 | AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append); | ||
938 | } | 1009 | } |
939 | catch (Exception e) | 1010 | catch (Exception e) |
940 | { | 1011 | { |
@@ -1076,7 +1147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1076 | AttachmentPt &= 0x7f; | 1147 | AttachmentPt &= 0x7f; |
1077 | 1148 | ||
1078 | // Calls attach with a Zero position | 1149 | // Calls attach with a Zero position |
1079 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) | 1150 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, false, append)) |
1080 | { | 1151 | { |
1081 | if (DebugLevel > 0) | 1152 | if (DebugLevel > 0) |
1082 | m_log.Debug( | 1153 | m_log.Debug( |
@@ -1138,4 +1209,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1138 | 1209 | ||
1139 | #endregion | 1210 | #endregion |
1140 | } | 1211 | } |
1141 | } \ No newline at end of file | 1212 | } |