diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 142 |
1 files changed, 97 insertions, 45 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8a3eeaa..6323160 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 | { |
@@ -75,40 +76,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
75 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | 76 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); |
76 | 77 | ||
77 | if (Enabled) | 78 | if (Enabled) |
78 | { | ||
79 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 79 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
80 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | ||
81 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | ||
82 | } | ||
83 | 80 | ||
84 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI | 81 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI |
85 | } | 82 | } |
86 | |||
87 | /// <summary> | ||
88 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. | ||
89 | /// </summary> | ||
90 | /// <param name='localID'></param> | ||
91 | /// <param name='itemID'></param> | ||
92 | private void HandleScriptStateChange(uint localID, bool started) | ||
93 | { | ||
94 | SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); | ||
95 | if (sog != null && sog.IsAttachment) | ||
96 | { | ||
97 | if (!started) | ||
98 | { | ||
99 | // FIXME: This is a convoluted way for working out whether the script state has changed to stop | ||
100 | // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below | ||
101 | // This needs to be handled in a less tangled way. | ||
102 | ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar); | ||
103 | if (sp.ControllingClient.IsActive) | ||
104 | sog.HasGroupChanged = true; | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | sog.HasGroupChanged = true; | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | 83 | ||
113 | public void RemoveRegion(Scene scene) | 84 | public void RemoveRegion(Scene scene) |
114 | { | 85 | { |
@@ -199,6 +170,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
199 | 170 | ||
200 | // 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); |
201 | 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 | |||
202 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 207 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); |
203 | foreach (AvatarAttachment attach in attachments) | 208 | foreach (AvatarAttachment attach in attachments) |
204 | { | 209 | { |
@@ -218,12 +223,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
218 | 223 | ||
219 | try | 224 | try |
220 | { | 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 | |||
221 | // 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 |
222 | // inventory right now. | 237 | // inventory right now. |
223 | if (sp.PresenceType == PresenceType.Npc) | 238 | if (sp.PresenceType == PresenceType.Npc) |
224 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); | 239 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); |
225 | else | 240 | else |
226 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p); | 241 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); |
227 | } | 242 | } |
228 | catch (Exception e) | 243 | catch (Exception e) |
229 | { | 244 | { |
@@ -268,13 +283,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
268 | 283 | ||
269 | sp.ClearAttachments(); | 284 | sp.ClearAttachments(); |
270 | } | 285 | } |
271 | 286 | ||
272 | 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) |
273 | { | 288 | { |
274 | if (!Enabled) | 289 | if (!Enabled) |
275 | return false; | 290 | return false; |
276 | 291 | ||
277 | if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) | 292 | if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp)) |
278 | { | 293 | { |
279 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | 294 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); |
280 | return true; | 295 | return true; |
@@ -283,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
283 | return false; | 298 | return false; |
284 | } | 299 | } |
285 | 300 | ||
286 | 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) |
287 | { | 302 | { |
288 | lock (sp.AttachmentsSyncLock) | 303 | lock (sp.AttachmentsSyncLock) |
289 | { | 304 | { |
@@ -338,6 +353,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
338 | attachPos = Vector3.Zero; | 353 | attachPos = Vector3.Zero; |
339 | } | 354 | } |
340 | 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 | } | ||
341 | group.AttachmentPoint = attachmentPt; | 374 | group.AttachmentPoint = attachmentPt; |
342 | group.AbsolutePosition = attachPos; | 375 | group.AbsolutePosition = attachPos; |
343 | 376 | ||
@@ -378,7 +411,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
378 | } | 411 | } |
379 | } | 412 | } |
380 | 413 | ||
381 | 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) | ||
382 | { | 420 | { |
383 | if (!Enabled) | 421 | if (!Enabled) |
384 | return null; | 422 | return null; |
@@ -417,7 +455,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
417 | return null; | 455 | return null; |
418 | } | 456 | } |
419 | 457 | ||
420 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); | 458 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); |
421 | } | 459 | } |
422 | 460 | ||
423 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 461 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -491,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
491 | so.AttachedAvatar = UUID.Zero; | 529 | so.AttachedAvatar = UUID.Zero; |
492 | rootPart.SetParentLocalId(0); | 530 | rootPart.SetParentLocalId(0); |
493 | so.ClearPartAttachmentData(); | 531 | so.ClearPartAttachmentData(); |
494 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); | 532 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false); |
495 | so.HasGroupChanged = true; | 533 | so.HasGroupChanged = true; |
496 | rootPart.Rezzed = DateTime.Now; | 534 | rootPart.Rezzed = DateTime.Now; |
497 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); | 535 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); |
@@ -803,8 +841,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
803 | UpdateDetachedObject(sp, so); | 841 | UpdateDetachedObject(sp, so); |
804 | } | 842 | } |
805 | 843 | ||
806 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 844 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
807 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) | 845 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) |
808 | { | 846 | { |
809 | if (m_invAccessModule == null) | 847 | if (m_invAccessModule == null) |
810 | return null; | 848 | return null; |
@@ -842,7 +880,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
842 | // This will throw if the attachment fails | 880 | // This will throw if the attachment fails |
843 | try | 881 | try |
844 | { | 882 | { |
845 | AttachObjectInternal(sp, objatt, attachmentPt, false, false); | 883 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, false); |
846 | } | 884 | } |
847 | catch (Exception e) | 885 | catch (Exception e) |
848 | { | 886 | { |
@@ -855,10 +893,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
855 | m_scene.DeleteSceneObject(objatt, false); | 893 | m_scene.DeleteSceneObject(objatt, false); |
856 | return null; | 894 | return null; |
857 | } | 895 | } |
858 | 896 | ||
859 | if (tainted) | 897 | if (tainted) |
860 | objatt.HasGroupChanged = true; | 898 | objatt.HasGroupChanged = true; |
861 | 899 | ||
900 | if (doc != null) | ||
901 | { | ||
902 | objatt.LoadScriptState(doc); | ||
903 | objatt.ResetOwnerChangeFlag(); | ||
904 | } | ||
905 | |||
862 | // Fire after attach, so we don't get messy perms dialogs | 906 | // Fire after attach, so we don't get messy perms dialogs |
863 | // 4 == AttachedRez | 907 | // 4 == AttachedRez |
864 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | 908 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); |
@@ -876,7 +920,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
876 | itemID, sp.Name, attachmentPt); | 920 | itemID, sp.Name, attachmentPt); |
877 | } | 921 | } |
878 | } | 922 | } |
879 | 923 | ||
880 | return null; | 924 | return null; |
881 | } | 925 | } |
882 | 926 | ||
@@ -999,7 +1043,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
999 | AttachmentPt &= 0x7f; | 1043 | AttachmentPt &= 0x7f; |
1000 | 1044 | ||
1001 | // Calls attach with a Zero position | 1045 | // Calls attach with a Zero position |
1002 | AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); | 1046 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false)) |
1047 | { | ||
1048 | // m_log.Debug( | ||
1049 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
1050 | // + ", AttachmentPoint: " + AttachmentPt); | ||
1051 | |||
1052 | // Save avatar attachment information | ||
1053 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | ||
1054 | } | ||
1003 | } | 1055 | } |
1004 | catch (Exception e) | 1056 | catch (Exception e) |
1005 | { | 1057 | { |