diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 112 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 10 |
2 files changed, 102 insertions, 20 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 24170fc..acd156e 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 | { |
@@ -169,6 +170,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
169 | 170 | ||
170 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); | 171 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); |
171 | 172 | ||
173 | XmlDocument doc = new XmlDocument(); | ||
174 | string stateData = String.Empty; | ||
175 | |||
176 | IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>(); | ||
177 | if (attServ != null) | ||
178 | { | ||
179 | m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); | ||
180 | stateData = attServ.Get(sp.UUID.ToString()); | ||
181 | if (stateData != String.Empty) | ||
182 | { | ||
183 | try | ||
184 | { | ||
185 | doc.LoadXml(stateData); | ||
186 | } | ||
187 | catch { } | ||
188 | } | ||
189 | } | ||
190 | |||
191 | Dictionary<UUID, string> itemData = new Dictionary<UUID, string>(); | ||
192 | |||
193 | XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); | ||
194 | if (nodes.Count > 0) | ||
195 | { | ||
196 | foreach (XmlNode n in nodes) | ||
197 | { | ||
198 | XmlElement elem = (XmlElement)n; | ||
199 | string itemID = elem.GetAttribute("ItemID"); | ||
200 | string xml = elem.InnerXml; | ||
201 | |||
202 | itemData[new UUID(itemID)] = xml; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | |||
172 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 207 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); |
173 | foreach (AvatarAttachment attach in attachments) | 208 | foreach (AvatarAttachment attach in attachments) |
174 | { | 209 | { |
@@ -188,12 +223,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
188 | 223 | ||
189 | try | 224 | try |
190 | { | 225 | { |
226 | string xmlData; | ||
227 | XmlDocument d = null; | ||
228 | UUID asset; | ||
229 | if (itemData.TryGetValue(attach.ItemID, out xmlData)) | ||
230 | { | ||
231 | d = new XmlDocument(); | ||
232 | d.LoadXml(xmlData); | ||
233 | m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID); | ||
234 | } | ||
235 | |||
191 | // 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 |
192 | // inventory right now. | 237 | // inventory right now. |
193 | if (sp.PresenceType == PresenceType.Npc) | 238 | if (sp.PresenceType == PresenceType.Npc) |
194 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); | 239 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); |
195 | else | 240 | else |
196 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p); | 241 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); |
197 | } | 242 | } |
198 | catch (Exception e) | 243 | catch (Exception e) |
199 | { | 244 | { |
@@ -238,13 +283,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
238 | 283 | ||
239 | sp.ClearAttachments(); | 284 | sp.ClearAttachments(); |
240 | } | 285 | } |
241 | 286 | ||
242 | 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 useAttachData, bool temp) |
243 | { | 288 | { |
244 | if (!Enabled) | 289 | if (!Enabled) |
245 | return false; | 290 | return false; |
246 | 291 | ||
247 | if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) | 292 | if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp)) |
248 | { | 293 | { |
249 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | 294 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); |
250 | return true; | 295 | return true; |
@@ -253,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
253 | return false; | 298 | return false; |
254 | } | 299 | } |
255 | 300 | ||
256 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) | 301 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) |
257 | { | 302 | { |
258 | lock (sp.AttachmentsSyncLock) | 303 | lock (sp.AttachmentsSyncLock) |
259 | { | 304 | { |
@@ -308,6 +353,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
308 | attachPos = Vector3.Zero; | 353 | attachPos = Vector3.Zero; |
309 | } | 354 | } |
310 | 355 | ||
356 | if (useAttachData) | ||
357 | { | ||
358 | group.RootPart.RotationOffset = group.RootPart.AttachRotation; | ||
359 | attachPos = group.RootPart.AttachOffset; | ||
360 | if (attachmentPt == 0) | ||
361 | { | ||
362 | attachmentPt = group.RootPart.AttachPoint; | ||
363 | if (attachmentPt == 0) | ||
364 | { | ||
365 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
366 | attachPos = Vector3.Zero; | ||
367 | } | ||
368 | } | ||
369 | else if (group.RootPart.AttachPoint != attachmentPt) | ||
370 | { | ||
371 | attachPos = Vector3.Zero; | ||
372 | } | ||
373 | } | ||
311 | group.AttachmentPoint = attachmentPt; | 374 | group.AttachmentPoint = attachmentPt; |
312 | group.AbsolutePosition = attachPos; | 375 | group.AbsolutePosition = attachPos; |
313 | 376 | ||
@@ -348,7 +411,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
348 | } | 411 | } |
349 | } | 412 | } |
350 | 413 | ||
351 | public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 414 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
415 | { | ||
416 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); | ||
417 | } | ||
418 | |||
419 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) | ||
352 | { | 420 | { |
353 | if (!Enabled) | 421 | if (!Enabled) |
354 | return null; | 422 | return null; |
@@ -387,7 +455,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
387 | return null; | 455 | return null; |
388 | } | 456 | } |
389 | 457 | ||
390 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); | 458 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); |
391 | } | 459 | } |
392 | 460 | ||
393 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 461 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -461,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
461 | so.AttachedAvatar = UUID.Zero; | 529 | so.AttachedAvatar = UUID.Zero; |
462 | rootPart.SetParentLocalId(0); | 530 | rootPart.SetParentLocalId(0); |
463 | so.ClearPartAttachmentData(); | 531 | so.ClearPartAttachmentData(); |
464 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); | 532 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false); |
465 | so.HasGroupChanged = true; | 533 | so.HasGroupChanged = true; |
466 | rootPart.Rezzed = DateTime.Now; | 534 | rootPart.Rezzed = DateTime.Now; |
467 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); | 535 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); |
@@ -778,8 +846,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
778 | UpdateDetachedObject(sp, so); | 846 | UpdateDetachedObject(sp, so); |
779 | } | 847 | } |
780 | 848 | ||
781 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 849 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
782 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) | 850 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) |
783 | { | 851 | { |
784 | if (m_invAccessModule == null) | 852 | if (m_invAccessModule == null) |
785 | return null; | 853 | return null; |
@@ -817,7 +885,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
817 | // This will throw if the attachment fails | 885 | // This will throw if the attachment fails |
818 | try | 886 | try |
819 | { | 887 | { |
820 | AttachObjectInternal(sp, objatt, attachmentPt, false, false); | 888 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, false); |
821 | } | 889 | } |
822 | catch (Exception e) | 890 | catch (Exception e) |
823 | { | 891 | { |
@@ -830,10 +898,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
830 | m_scene.DeleteSceneObject(objatt, false); | 898 | m_scene.DeleteSceneObject(objatt, false); |
831 | return null; | 899 | return null; |
832 | } | 900 | } |
833 | 901 | ||
834 | if (tainted) | 902 | if (tainted) |
835 | objatt.HasGroupChanged = true; | 903 | objatt.HasGroupChanged = true; |
836 | 904 | ||
905 | if (doc != null) | ||
906 | { | ||
907 | objatt.LoadScriptState(doc); | ||
908 | objatt.ResetOwnerChangeFlag(); | ||
909 | } | ||
910 | |||
837 | // Fire after attach, so we don't get messy perms dialogs | 911 | // Fire after attach, so we don't get messy perms dialogs |
838 | // 4 == AttachedRez | 912 | // 4 == AttachedRez |
839 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | 913 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); |
@@ -851,7 +925,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
851 | itemID, sp.Name, attachmentPt); | 925 | itemID, sp.Name, attachmentPt); |
852 | } | 926 | } |
853 | } | 927 | } |
854 | 928 | ||
855 | return null; | 929 | return null; |
856 | } | 930 | } |
857 | 931 | ||
@@ -974,7 +1048,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
974 | AttachmentPt &= 0x7f; | 1048 | AttachmentPt &= 0x7f; |
975 | 1049 | ||
976 | // Calls attach with a Zero position | 1050 | // Calls attach with a Zero position |
977 | AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); | 1051 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false)) |
1052 | { | ||
1053 | // m_log.Debug( | ||
1054 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
1055 | // + ", AttachmentPoint: " + AttachmentPt); | ||
1056 | |||
1057 | // Save avatar attachment information | ||
1058 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | ||
1059 | } | ||
978 | } | 1060 | } |
979 | catch (Exception e) | 1061 | catch (Exception e) |
980 | { | 1062 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 0ee01c7..4e9d3f9 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)); |
@@ -438,7 +438,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
438 | scene.EventManager.OnChatFromWorld += OnChatFromWorld; | 438 | scene.EventManager.OnChatFromWorld += OnChatFromWorld; |
439 | 439 | ||
440 | SceneObjectGroup rezzedSo | 440 | SceneObjectGroup rezzedSo |
441 | = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | 441 | = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest)); |
442 | 442 | ||
443 | // Wait for chat to signal rezzed script has been started. | 443 | // Wait for chat to signal rezzed script has been started. |
444 | m_chatEvent.WaitOne(60000); | 444 | m_chatEvent.WaitOne(60000); |
@@ -457,7 +457,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
457 | Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); | 457 | Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); |
458 | 458 | ||
459 | // Re-rez the attachment to check script running state | 459 | // Re-rez the attachment to check script running state |
460 | SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | 460 | SceneObjectGroup reRezzedSo = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest)); |
461 | 461 | ||
462 | // Wait for chat to signal rezzed script has been started. | 462 | // Wait for chat to signal rezzed script has been started. |
463 | m_chatEvent.WaitOne(60000); | 463 | m_chatEvent.WaitOne(60000); |
@@ -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 | } |