aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs142
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;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Services.Interfaces;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.Attachments 45namespace 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 {