diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
18 files changed, 1120 insertions, 509 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index fd7cad2..394b90a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 51 | ||
52 | private Scene m_scene; | 52 | private Scene m_scene; |
53 | private IDialogModule m_dialogModule; | 53 | private IInventoryAccessModule m_invAccessModule; |
54 | 54 | ||
55 | /// <summary> | 55 | /// <summary> |
56 | /// Are attachments enabled? | 56 | /// Are attachments enabled? |
@@ -72,7 +72,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
72 | public void AddRegion(Scene scene) | 72 | public void AddRegion(Scene scene) |
73 | { | 73 | { |
74 | m_scene = scene; | 74 | m_scene = scene; |
75 | m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); | ||
76 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | 75 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); |
77 | 76 | ||
78 | if (Enabled) | 77 | if (Enabled) |
@@ -89,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
89 | m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; | 88 | m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; |
90 | } | 89 | } |
91 | 90 | ||
92 | public void RegionLoaded(Scene scene) {} | 91 | public void RegionLoaded(Scene scene) |
92 | { | ||
93 | m_invAccessModule = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | ||
94 | } | ||
93 | 95 | ||
94 | public void Close() | 96 | public void Close() |
95 | { | 97 | { |
@@ -100,6 +102,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
100 | 102 | ||
101 | #region IAttachmentsModule | 103 | #region IAttachmentsModule |
102 | 104 | ||
105 | public void CopyAttachments(IScenePresence sp, AgentData ad) | ||
106 | { | ||
107 | lock (sp.AttachmentsSyncLock) | ||
108 | { | ||
109 | // Attachment objects | ||
110 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
111 | if (attachments.Count > 0) | ||
112 | { | ||
113 | ad.AttachmentObjects = new List<ISceneObject>(); | ||
114 | ad.AttachmentObjectStates = new List<string>(); | ||
115 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
116 | sp.InTransitScriptStates.Clear(); | ||
117 | |||
118 | foreach (SceneObjectGroup sog in attachments) | ||
119 | { | ||
120 | // We need to make a copy and pass that copy | ||
121 | // because of transfers withn the same sim | ||
122 | ISceneObject clone = sog.CloneForNewScene(); | ||
123 | // Attachment module assumes that GroupPosition holds the offsets...! | ||
124 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | ||
125 | ((SceneObjectGroup)clone).IsAttachment = false; | ||
126 | ad.AttachmentObjects.Add(clone); | ||
127 | string state = sog.GetStateSnapshot(); | ||
128 | ad.AttachmentObjectStates.Add(state); | ||
129 | sp.InTransitScriptStates.Add(state); | ||
130 | // Let's remove the scripts of the original object here | ||
131 | sog.RemoveScriptInstances(true); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | public void CopyAttachments(AgentData ad, IScenePresence sp) | ||
138 | { | ||
139 | if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) | ||
140 | { | ||
141 | lock (sp.AttachmentsSyncLock) | ||
142 | sp.ClearAttachments(); | ||
143 | |||
144 | int i = 0; | ||
145 | foreach (ISceneObject so in ad.AttachmentObjects) | ||
146 | { | ||
147 | ((SceneObjectGroup)so).LocalId = 0; | ||
148 | ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); | ||
149 | so.SetState(ad.AttachmentObjectStates[i++], m_scene); | ||
150 | m_scene.IncomingCreateObject(Vector3.Zero, so); | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
103 | /// <summary> | 155 | /// <summary> |
104 | /// RezAttachments. This should only be called upon login on the first region. | 156 | /// RezAttachments. This should only be called upon login on the first region. |
105 | /// Attachment rezzings on crossings and TPs are done in a different way. | 157 | /// Attachment rezzings on crossings and TPs are done in a different way. |
@@ -185,40 +237,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
185 | if (sp.PresenceType == PresenceType.Npc) | 237 | if (sp.PresenceType == PresenceType.Npc) |
186 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); | 238 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); |
187 | else | 239 | else |
188 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, true, d); | 240 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); |
189 | } | 241 | } |
190 | catch (Exception e) | 242 | catch (Exception e) |
191 | { | 243 | { |
192 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); | 244 | UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId; |
245 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}", | ||
246 | attach.ItemID, attach.AssetID, p, agentId, e.Message, e.StackTrace); | ||
193 | } | 247 | } |
194 | } | 248 | } |
195 | } | 249 | } |
196 | 250 | ||
197 | public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted) | 251 | public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) |
198 | { | 252 | { |
199 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
200 | |||
201 | if (!Enabled) | 253 | if (!Enabled) |
202 | return; | 254 | return; |
203 | 255 | ||
204 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 256 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); |
257 | |||
258 | lock (sp.AttachmentsSyncLock) | ||
205 | { | 259 | { |
206 | grp.IsAttachment = false; | 260 | foreach (SceneObjectGroup so in sp.GetAttachments()) |
207 | grp.AbsolutePosition = grp.RootPart.AttachedPos; | 261 | { |
208 | UpdateKnownItem(sp, grp, saveAllScripted); | 262 | // We can only remove the script instances from the script engine after we've retrieved their xml state |
209 | grp.IsAttachment = true; | 263 | // when we update the attachment item. |
264 | m_scene.DeleteSceneObject(so, false, false); | ||
265 | |||
266 | if (saveChanged || saveAllScripted) | ||
267 | { | ||
268 | so.IsAttachment = false; | ||
269 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
270 | UpdateKnownItem(sp, so, saveAllScripted); | ||
271 | } | ||
272 | |||
273 | so.RemoveScriptInstances(true); | ||
274 | } | ||
275 | |||
276 | sp.ClearAttachments(); | ||
210 | } | 277 | } |
211 | } | 278 | } |
212 | 279 | ||
213 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) | 280 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) |
214 | { | 281 | { |
215 | // m_log.DebugFormat( | ||
216 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
217 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
218 | |||
219 | if (!Enabled) | 282 | if (!Enabled) |
220 | return; | 283 | return; |
221 | 284 | ||
285 | // m_log.DebugFormat( | ||
286 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
287 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
288 | |||
222 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 289 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
223 | { | 290 | { |
224 | sop.Scene.DeleteSceneObject(sop, silent); | 291 | sop.Scene.DeleteSceneObject(sop, silent); |
@@ -234,6 +301,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
234 | // m_log.DebugFormat( | 301 | // m_log.DebugFormat( |
235 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | 302 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
236 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | 303 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); |
304 | |||
305 | if (group.GetSittingAvatarsCount() != 0) | ||
306 | { | ||
307 | // m_log.WarnFormat( | ||
308 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | ||
309 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | ||
310 | |||
311 | return false; | ||
312 | } | ||
237 | 313 | ||
238 | if (sp.GetAttachments(attachmentPt).Contains(group)) | 314 | if (sp.GetAttachments(attachmentPt).Contains(group)) |
239 | { | 315 | { |
@@ -294,32 +370,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
294 | group.AttachmentPoint = attachmentPt; | 370 | group.AttachmentPoint = attachmentPt; |
295 | group.AbsolutePosition = attachPos; | 371 | group.AbsolutePosition = attachPos; |
296 | 372 | ||
297 | // We also don't want to do any of the inventory operations for an NPC. | ||
298 | if (sp.PresenceType != PresenceType.Npc) | 373 | if (sp.PresenceType != PresenceType.Npc) |
299 | { | 374 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt); |
300 | // Remove any previous attachments | ||
301 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
302 | |||
303 | // At the moment we can only deal with a single attachment | ||
304 | if (attachments.Count != 0) | ||
305 | { | ||
306 | UUID oldAttachmentItemID = attachments[0].FromItemID; | ||
307 | |||
308 | if (oldAttachmentItemID != UUID.Zero) | ||
309 | DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); | ||
310 | else | ||
311 | m_log.WarnFormat( | ||
312 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | ||
313 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
314 | } | ||
315 | |||
316 | // Add the new attachment to inventory if we don't already have it. | ||
317 | UUID newAttachmentItemID = group.FromItemID; | ||
318 | if (newAttachmentItemID == UUID.Zero) | ||
319 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
320 | |||
321 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
322 | } | ||
323 | 375 | ||
324 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | 376 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
325 | } | 377 | } |
@@ -327,12 +379,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
327 | return true; | 379 | return true; |
328 | } | 380 | } |
329 | 381 | ||
382 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt) | ||
383 | { | ||
384 | // Remove any previous attachments | ||
385 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
386 | |||
387 | // At the moment we can only deal with a single attachment | ||
388 | if (attachments.Count != 0) | ||
389 | { | ||
390 | if (attachments[0].FromItemID != UUID.Zero) | ||
391 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | ||
392 | else | ||
393 | m_log.WarnFormat( | ||
394 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | ||
395 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
396 | } | ||
397 | |||
398 | // Add the new attachment to inventory if we don't already have it. | ||
399 | UUID newAttachmentItemID = group.FromItemID; | ||
400 | if (newAttachmentItemID == UUID.Zero) | ||
401 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
402 | |||
403 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
404 | } | ||
405 | |||
330 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 406 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
331 | { | 407 | { |
332 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, true, null); | 408 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); |
333 | } | 409 | } |
334 | 410 | ||
335 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) | 411 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) |
336 | { | 412 | { |
337 | if (!Enabled) | 413 | if (!Enabled) |
338 | return null; | 414 | return null; |
@@ -371,12 +447,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
371 | return null; | 447 | return null; |
372 | } | 448 | } |
373 | 449 | ||
374 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); | 450 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); |
375 | |||
376 | if (att == null) | ||
377 | DetachSingleAttachmentToInv(sp, itemID); | ||
378 | |||
379 | return att; | ||
380 | } | 451 | } |
381 | 452 | ||
382 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 453 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -453,18 +524,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
453 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 524 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
454 | } | 525 | } |
455 | 526 | ||
456 | public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) | 527 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
457 | { | 528 | { |
458 | lock (sp.AttachmentsSyncLock) | 529 | lock (sp.AttachmentsSyncLock) |
459 | { | 530 | { |
460 | // Save avatar attachment information | 531 | // Save avatar attachment information |
461 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 532 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
533 | |||
534 | if (so.AttachedAvatar != sp.UUID) | ||
535 | { | ||
536 | m_log.WarnFormat( | ||
537 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
538 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
462 | 539 | ||
463 | bool changed = sp.Appearance.DetachAttachment(itemID); | 540 | return; |
541 | } | ||
542 | |||
543 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); | ||
464 | if (changed && m_scene.AvatarFactory != null) | 544 | if (changed && m_scene.AvatarFactory != null) |
465 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 545 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
466 | 546 | ||
467 | DetachSingleAttachmentToInvInternal(sp, itemID); | 547 | DetachSingleAttachmentToInvInternal(sp, so); |
468 | } | 548 | } |
469 | } | 549 | } |
470 | 550 | ||
@@ -473,17 +553,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
473 | if (!Enabled) | 553 | if (!Enabled) |
474 | return; | 554 | return; |
475 | 555 | ||
476 | // First we save the | ||
477 | // attachment point information, then we update the relative | ||
478 | // positioning. Then we have to mark the object as NOT an | ||
479 | // attachment. This is necessary in order to correctly save | ||
480 | // and retrieve GroupPosition information for the attachment. | ||
481 | // Finally, we restore the object's attachment status. | ||
482 | uint attachmentPoint = sog.AttachmentPoint; | ||
483 | sog.UpdateGroupPosition(pos); | 556 | sog.UpdateGroupPosition(pos); |
484 | sog.IsAttachment = false; | ||
485 | sog.AbsolutePosition = sog.RootPart.AttachedPos; | ||
486 | sog.AttachmentPoint = attachmentPoint; | ||
487 | sog.HasGroupChanged = true; | 557 | sog.HasGroupChanged = true; |
488 | } | 558 | } |
489 | 559 | ||
@@ -526,6 +596,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
526 | /// </remarks> | 596 | /// </remarks> |
527 | /// <param name="sp"></param> | 597 | /// <param name="sp"></param> |
528 | /// <param name="grp"></param> | 598 | /// <param name="grp"></param> |
599 | /// <param name="saveAllScripted"></param> | ||
529 | private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) | 600 | private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) |
530 | { | 601 | { |
531 | // Saving attachments for NPCs messes them up for the real owner! | 602 | // Saving attachments for NPCs messes them up for the real owner! |
@@ -538,9 +609,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
538 | 609 | ||
539 | if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) | 610 | if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) |
540 | { | 611 | { |
541 | m_log.DebugFormat( | 612 | // m_log.DebugFormat( |
542 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", | 613 | // "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", |
543 | grp.UUID, grp.AttachmentPoint); | 614 | // grp.UUID, grp.AttachmentPoint); |
544 | 615 | ||
545 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | 616 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); |
546 | 617 | ||
@@ -571,12 +642,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
571 | } | 642 | } |
572 | grp.HasGroupChanged = false; // Prevent it being saved over and over | 643 | grp.HasGroupChanged = false; // Prevent it being saved over and over |
573 | } | 644 | } |
574 | else | 645 | // else |
575 | { | 646 | // { |
576 | m_log.DebugFormat( | 647 | // m_log.DebugFormat( |
577 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | 648 | // "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", |
578 | grp.UUID, grp.AttachmentPoint); | 649 | // grp.UUID, grp.AttachmentPoint); |
579 | } | 650 | // } |
580 | } | 651 | } |
581 | 652 | ||
582 | /// <summary> | 653 | /// <summary> |
@@ -594,9 +665,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
594 | private void AttachToAgent( | 665 | private void AttachToAgent( |
595 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 666 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
596 | { | 667 | { |
597 | // m_log.DebugFormat( | 668 | // m_log.DebugFormat( |
598 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 669 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", |
599 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 670 | // so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); |
600 | 671 | ||
601 | so.DetachFromBackup(); | 672 | so.DetachFromBackup(); |
602 | 673 | ||
@@ -627,6 +698,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
627 | { | 698 | { |
628 | m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); | 699 | m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); |
629 | } | 700 | } |
701 | else if (so.HasPrivateAttachmentPoint) | ||
702 | { | ||
703 | // m_log.DebugFormat( | ||
704 | // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", | ||
705 | // so.Name, sp.Name, so.AttachmentPoint); | ||
706 | |||
707 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the | ||
708 | // scene that it's no longer in their awareness. | ||
709 | m_scene.ForEachClient( | ||
710 | client => | ||
711 | { if (client.AgentId != so.AttachedAvatar) | ||
712 | client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId }); | ||
713 | }); | ||
714 | } | ||
630 | 715 | ||
631 | so.IsSelected = false; // fudge.... | 716 | so.IsSelected = false; // fudge.... |
632 | so.ScheduleGroupForFullUpdate(); | 717 | so.ScheduleGroupForFullUpdate(); |
@@ -645,210 +730,124 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
645 | /// <returns>The user inventory item created that holds the attachment.</returns> | 730 | /// <returns>The user inventory item created that holds the attachment.</returns> |
646 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) | 731 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) |
647 | { | 732 | { |
733 | if (m_invAccessModule == null) | ||
734 | return null; | ||
735 | |||
648 | // m_log.DebugFormat( | 736 | // m_log.DebugFormat( |
649 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | 737 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", |
650 | // grp.Name, grp.LocalId, remoteClient.Name); | 738 | // grp.Name, grp.LocalId, remoteClient.Name); |
651 | 739 | ||
652 | // Vector3 inventoryStoredPosition = new Vector3 | 740 | InventoryItemBase newItem |
653 | // (((grp.AbsolutePosition.X > (int)Constants.RegionSize) | 741 | = m_invAccessModule.CopyToInventory( |
654 | // ? (float)Constants.RegionSize - 6 | 742 | DeRezAction.TakeCopy, |
655 | // : grp.AbsolutePosition.X) | 743 | m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, |
656 | // , | 744 | new List<SceneObjectGroup> { grp }, |
657 | // (grp.AbsolutePosition.Y > (int)Constants.RegionSize) | 745 | sp.ControllingClient, true)[0]; |
658 | // ? (float)Constants.RegionSize - 6 | ||
659 | // : grp.AbsolutePosition.Y, | ||
660 | // grp.AbsolutePosition.Z); | ||
661 | // | ||
662 | // Vector3 originalPosition = grp.AbsolutePosition; | ||
663 | // | ||
664 | // grp.AbsolutePosition = inventoryStoredPosition; | ||
665 | |||
666 | // If we're being called from a script, then trying to serialize that same script's state will not complete | ||
667 | // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if | ||
668 | // the client/server crashes rather than logging out normally, the attachment's scripts will resume | ||
669 | // without state on relog. Arguably, this is what we want anyway. | ||
670 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); | ||
671 | |||
672 | // grp.AbsolutePosition = originalPosition; | ||
673 | |||
674 | AssetBase asset = m_scene.CreateAsset( | ||
675 | grp.GetPartName(grp.LocalId), | ||
676 | grp.GetPartDescription(grp.LocalId), | ||
677 | (sbyte)AssetType.Object, | ||
678 | Utils.StringToBytes(sceneObjectXml), | ||
679 | sp.UUID); | ||
680 | |||
681 | m_scene.AssetService.Store(asset); | ||
682 | |||
683 | InventoryItemBase item = new InventoryItemBase(); | ||
684 | item.CreatorId = grp.RootPart.CreatorID.ToString(); | ||
685 | item.CreatorData = grp.RootPart.CreatorData; | ||
686 | item.Owner = sp.UUID; | ||
687 | item.ID = UUID.Random(); | ||
688 | item.AssetID = asset.FullID; | ||
689 | item.Description = asset.Description; | ||
690 | item.Name = asset.Name; | ||
691 | item.AssetType = asset.Type; | ||
692 | item.InvType = (int)InventoryType.Object; | ||
693 | |||
694 | InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
695 | if (folder != null) | ||
696 | item.Folder = folder.ID; | ||
697 | else // oopsies | ||
698 | item.Folder = UUID.Zero; | ||
699 | |||
700 | // Nix the special bits we used to use for slam and the folded perms | ||
701 | uint allowablePermissionsMask = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move); | ||
702 | |||
703 | if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) | ||
704 | { | ||
705 | item.BasePermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
706 | item.CurrentPermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
707 | item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
708 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
709 | item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
710 | } | ||
711 | else | ||
712 | { | ||
713 | item.BasePermissions = grp.RootPart.BaseMask & allowablePermissionsMask; | ||
714 | item.CurrentPermissions = grp.RootPart.OwnerMask & allowablePermissionsMask; | ||
715 | item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
716 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & allowablePermissionsMask; | ||
717 | item.GroupPermissions = grp.RootPart.GroupMask & allowablePermissionsMask; | ||
718 | } | ||
719 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
720 | 746 | ||
721 | // sets itemID so client can show item as 'attached' in inventory | 747 | // sets itemID so client can show item as 'attached' in inventory |
722 | grp.FromItemID = item.ID; | 748 | grp.FromItemID = newItem.ID; |
723 | |||
724 | if (m_scene.AddInventoryItem(item)) | ||
725 | { | ||
726 | sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | if (m_dialogModule != null) | ||
731 | m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); | ||
732 | } | ||
733 | 749 | ||
734 | return item; | 750 | return newItem; |
735 | } | 751 | } |
736 | 752 | ||
737 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | 753 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) |
738 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
739 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) | ||
740 | { | 754 | { |
741 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | 755 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); |
742 | 756 | ||
743 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 757 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); |
744 | return; | 758 | sp.RemoveAttachment(so); |
745 | |||
746 | // We can NOT use the dictionries here, as we are looking | ||
747 | // for an entity by the fromAssetID, which is NOT the prim UUID | ||
748 | EntityBase[] detachEntities = m_scene.GetEntities(); | ||
749 | SceneObjectGroup group; | ||
750 | |||
751 | lock (sp.AttachmentsSyncLock) | ||
752 | { | ||
753 | foreach (EntityBase entity in detachEntities) | ||
754 | { | ||
755 | if (entity is SceneObjectGroup) | ||
756 | { | ||
757 | group = (SceneObjectGroup)entity; | ||
758 | if (group.FromItemID == itemID) | ||
759 | { | ||
760 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | ||
761 | sp.RemoveAttachment(group); | ||
762 | 759 | ||
763 | // Prepare sog for storage | 760 | // We can only remove the script instances from the script engine after we've retrieved their xml state |
764 | group.AttachedAvatar = UUID.Zero; | 761 | // when we update the attachment item. |
765 | group.RootPart.SetParentLocalId(0); | 762 | m_scene.DeleteSceneObject(so, false, false); |
766 | group.IsAttachment = false; | ||
767 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
768 | 763 | ||
769 | UpdateKnownItem(sp, group, true); | 764 | // Prepare sog for storage |
770 | m_scene.DeleteSceneObject(group, false); | 765 | so.AttachedAvatar = UUID.Zero; |
766 | so.RootPart.SetParentLocalId(0); | ||
767 | so.IsAttachment = false; | ||
768 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
771 | 769 | ||
772 | return; | 770 | UpdateKnownItem(sp, so, true); |
773 | } | 771 | so.RemoveScriptInstances(true); |
774 | } | ||
775 | } | ||
776 | } | ||
777 | } | 772 | } |
778 | 773 | ||
779 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 774 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
780 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) | 775 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) |
781 | { | 776 | { |
782 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | 777 | if (m_invAccessModule == null) |
783 | if (invAccess != null) | 778 | return null; |
779 | |||
780 | lock (sp.AttachmentsSyncLock) | ||
784 | { | 781 | { |
785 | lock (sp.AttachmentsSyncLock) | 782 | SceneObjectGroup objatt; |
783 | |||
784 | if (itemID != UUID.Zero) | ||
785 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
786 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
787 | false, false, sp.UUID, true); | ||
788 | else | ||
789 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
790 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
791 | false, false, sp.UUID, true); | ||
792 | |||
793 | if (objatt != null) | ||
786 | { | 794 | { |
787 | SceneObjectGroup objatt; | 795 | // m_log.DebugFormat( |
788 | 796 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | |
789 | if (itemID != UUID.Zero) | 797 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); |
790 | objatt = invAccess.RezObject(sp.ControllingClient, | 798 | |
791 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | 799 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
792 | false, false, sp.UUID, true); | 800 | objatt.HasGroupChanged = false; |
793 | else | 801 | bool tainted = false; |
794 | objatt = invAccess.RezObject(sp.ControllingClient, | 802 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) |
795 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | 803 | tainted = true; |
796 | false, false, sp.UUID, true); | 804 | |
797 | 805 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | |
798 | // m_log.DebugFormat( | 806 | // course of events. If not, then it's probably not worth trying to recover the situation |
799 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | 807 | // since this is more likely to trigger further exceptions and confuse later debugging. If |
800 | // objatt.Name, remoteClient.Name, AttachmentPt); | 808 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent |
801 | 809 | // since other normal error conditions will simply return false instead. | |
802 | if (objatt != null) | 810 | // This will throw if the attachment fails |
811 | try | ||
803 | { | 812 | { |
804 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 813 | AttachObject(sp, objatt, attachmentPt, false, false); |
805 | objatt.HasGroupChanged = false; | ||
806 | bool tainted = false; | ||
807 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
808 | tainted = true; | ||
809 | |||
810 | // This will throw if the attachment fails | ||
811 | try | ||
812 | { | ||
813 | AttachObject(sp, objatt, attachmentPt, false, false); | ||
814 | } | ||
815 | catch (Exception e) | ||
816 | { | ||
817 | m_log.ErrorFormat( | ||
818 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
819 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
820 | |||
821 | // Make sure the object doesn't stick around and bail | ||
822 | sp.RemoveAttachment(objatt); | ||
823 | m_scene.DeleteSceneObject(objatt, false); | ||
824 | return null; | ||
825 | } | ||
826 | |||
827 | if (tainted) | ||
828 | objatt.HasGroupChanged = true; | ||
829 | |||
830 | if (doc != null) | ||
831 | { | ||
832 | objatt.LoadScriptState(doc); | ||
833 | objatt.ResetOwnerChangeFlag(); | ||
834 | } | ||
835 | |||
836 | // Fire after attach, so we don't get messy perms dialogs | ||
837 | // 4 == AttachedRez | ||
838 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
839 | objatt.ResumeScripts(); | ||
840 | |||
841 | // Do this last so that event listeners have access to all the effects of the attachment | ||
842 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
843 | |||
844 | return objatt; | ||
845 | } | 814 | } |
846 | else | 815 | catch (Exception e) |
816 | { | ||
817 | m_log.ErrorFormat( | ||
818 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
819 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
820 | |||
821 | // Make sure the object doesn't stick around and bail | ||
822 | sp.RemoveAttachment(objatt); | ||
823 | m_scene.DeleteSceneObject(objatt, false); | ||
824 | return null; | ||
825 | } | ||
826 | |||
827 | if (tainted) | ||
828 | objatt.HasGroupChanged = true; | ||
829 | |||
830 | if (doc != null) | ||
847 | { | 831 | { |
848 | m_log.WarnFormat( | 832 | objatt.LoadScriptState(doc); |
849 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | 833 | objatt.ResetOwnerChangeFlag(); |
850 | itemID, sp.Name, attachmentPt); | ||
851 | } | 834 | } |
835 | |||
836 | // Fire after attach, so we don't get messy perms dialogs | ||
837 | // 4 == AttachedRez | ||
838 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
839 | objatt.ResumeScripts(); | ||
840 | |||
841 | // Do this last so that event listeners have access to all the effects of the attachment | ||
842 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
843 | |||
844 | return objatt; | ||
845 | } | ||
846 | else | ||
847 | { | ||
848 | m_log.WarnFormat( | ||
849 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
850 | itemID, sp.Name, attachmentPt); | ||
852 | } | 851 | } |
853 | } | 852 | } |
854 | 853 | ||
@@ -864,9 +863,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
864 | /// <param name="att"></param> | 863 | /// <param name="att"></param> |
865 | private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) | 864 | private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) |
866 | { | 865 | { |
867 | // m_log.DebugFormat( | 866 | // m_log.DebugFormat( |
868 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", | 867 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", |
869 | // att.Name, sp.Name, AttachmentPt, itemID); | 868 | // att.Name, sp.Name, AttachmentPt, itemID); |
870 | 869 | ||
871 | if (UUID.Zero == itemID) | 870 | if (UUID.Zero == itemID) |
872 | { | 871 | { |
@@ -884,7 +883,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
884 | item = m_scene.InventoryService.GetItem(item); | 883 | item = m_scene.InventoryService.GetItem(item); |
885 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); | 884 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); |
886 | if (changed && m_scene.AvatarFactory != null) | 885 | if (changed && m_scene.AvatarFactory != null) |
886 | { | ||
887 | // m_log.DebugFormat( | ||
888 | // "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", | ||
889 | // sp.Name, att.Name, AttachmentPt); | ||
890 | |||
887 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 891 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
892 | } | ||
888 | } | 893 | } |
889 | 894 | ||
890 | #endregion | 895 | #endregion |
@@ -929,9 +934,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
929 | 934 | ||
930 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 935 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
931 | { | 936 | { |
932 | // m_log.DebugFormat( | 937 | // m_log.DebugFormat( |
933 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 938 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", |
934 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); | 939 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); |
935 | 940 | ||
936 | if (!Enabled) | 941 | if (!Enabled) |
937 | return; | 942 | return; |
@@ -967,13 +972,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
967 | // Calls attach with a Zero position | 972 | // Calls attach with a Zero position |
968 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true)) | 973 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true)) |
969 | { | 974 | { |
970 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | 975 | // m_log.Debug( |
976 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
977 | // + ", AttachmentPoint: " + AttachmentPt); | ||
971 | 978 | ||
972 | // Save avatar attachment information | 979 | // Save avatar attachment information |
973 | m_log.Debug( | 980 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); |
974 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
975 | + ", AttachmentPoint: " + AttachmentPt); | ||
976 | |||
977 | } | 981 | } |
978 | } | 982 | } |
979 | catch (Exception e) | 983 | catch (Exception e) |
@@ -989,8 +993,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
989 | 993 | ||
990 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 994 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
991 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 995 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
996 | |||
992 | if (sp != null && group != null) | 997 | if (sp != null && group != null) |
993 | DetachSingleAttachmentToInv(sp, group.FromItemID); | 998 | DetachSingleAttachmentToInv(sp, group); |
994 | } | 999 | } |
995 | 1000 | ||
996 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) | 1001 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) |
@@ -1000,7 +1005,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1000 | 1005 | ||
1001 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1006 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1002 | if (sp != null) | 1007 | if (sp != null) |
1003 | DetachSingleAttachmentToInv(sp, itemID); | 1008 | { |
1009 | lock (sp.AttachmentsSyncLock) | ||
1010 | { | ||
1011 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
1012 | |||
1013 | foreach (SceneObjectGroup group in attachments) | ||
1014 | { | ||
1015 | if (group.FromItemID == itemID) | ||
1016 | { | ||
1017 | DetachSingleAttachmentToInv(sp, group); | ||
1018 | return; | ||
1019 | } | ||
1020 | } | ||
1021 | } | ||
1022 | } | ||
1004 | } | 1023 | } |
1005 | 1024 | ||
1006 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) | 1025 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 7119ad2..cd1e1c1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | using System.Timers; | 33 | using System.Timers; |
34 | using System.Xml; | ||
34 | using Timer=System.Timers.Timer; | 35 | using Timer=System.Timers.Timer; |
35 | using Nini.Config; | 36 | using Nini.Config; |
36 | using NUnit.Framework; | 37 | using NUnit.Framework; |
@@ -38,11 +39,16 @@ using OpenMetaverse; | |||
38 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Communications; | 40 | using OpenSim.Framework.Communications; |
40 | using OpenSim.Region.CoreModules.Avatar.Attachments; | 41 | using OpenSim.Region.CoreModules.Avatar.Attachments; |
42 | using OpenSim.Region.CoreModules.Framework; | ||
43 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | ||
41 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | 44 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; |
42 | using OpenSim.Region.CoreModules.World.Serialiser; | 45 | using OpenSim.Region.CoreModules.Scripting.WorldComm; |
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 46 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
47 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
44 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
45 | using OpenSim.Region.Framework.Interfaces; | 49 | using OpenSim.Region.Framework.Interfaces; |
50 | using OpenSim.Region.ScriptEngine.XEngine; | ||
51 | using OpenSim.Services.Interfaces; | ||
46 | using OpenSim.Tests.Common; | 52 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | 53 | using OpenSim.Tests.Common.Mock; |
48 | 54 | ||
@@ -52,11 +58,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
52 | /// Attachment tests | 58 | /// Attachment tests |
53 | /// </summary> | 59 | /// </summary> |
54 | [TestFixture] | 60 | [TestFixture] |
55 | public class AttachmentsModuleTests | 61 | public class AttachmentsModuleTests : OpenSimTestCase |
56 | { | 62 | { |
57 | private Scene scene; | 63 | private AutoResetEvent m_chatEvent = new AutoResetEvent(false); |
58 | private AttachmentsModule m_attMod; | 64 | private OSChatMessage m_osChatMessageReceived; |
59 | private ScenePresence m_presence; | ||
60 | 65 | ||
61 | [TestFixtureSetUp] | 66 | [TestFixtureSetUp] |
62 | public void FixtureInit() | 67 | public void FixtureInit() |
@@ -65,52 +70,129 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
65 | Util.FireAndForgetMethod = FireAndForgetMethod.None; | 70 | Util.FireAndForgetMethod = FireAndForgetMethod.None; |
66 | } | 71 | } |
67 | 72 | ||
68 | [SetUp] | 73 | [TestFixtureTearDown] |
69 | public void Init() | 74 | public void TearDown() |
75 | { | ||
76 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
77 | // threads. Possibly, later tests should be rewritten not to worry about such things. | ||
78 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
79 | } | ||
80 | |||
81 | private void OnChatFromWorld(object sender, OSChatMessage oscm) | ||
82 | { | ||
83 | // Console.WriteLine("Got chat [{0}]", oscm.Message); | ||
84 | |||
85 | m_osChatMessageReceived = oscm; | ||
86 | m_chatEvent.Set(); | ||
87 | } | ||
88 | |||
89 | private Scene CreateTestScene() | ||
70 | { | 90 | { |
71 | IConfigSource config = new IniConfigSource(); | 91 | IConfigSource config = new IniConfigSource(); |
92 | List<object> modules = new List<object>(); | ||
93 | |||
94 | AddCommonConfig(config, modules); | ||
95 | |||
96 | Scene scene | ||
97 | = new SceneHelpers().SetupScene( | ||
98 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); | ||
99 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); | ||
100 | |||
101 | return scene; | ||
102 | } | ||
103 | |||
104 | private Scene CreateScriptingEnabledTestScene() | ||
105 | { | ||
106 | IConfigSource config = new IniConfigSource(); | ||
107 | List<object> modules = new List<object>(); | ||
108 | |||
109 | AddCommonConfig(config, modules); | ||
110 | AddScriptingConfig(config, modules); | ||
111 | |||
112 | Scene scene | ||
113 | = new SceneHelpers().SetupScene( | ||
114 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); | ||
115 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); | ||
116 | |||
117 | scene.StartScripts(); | ||
118 | |||
119 | return scene; | ||
120 | } | ||
121 | |||
122 | private void AddCommonConfig(IConfigSource config, List<object> modules) | ||
123 | { | ||
72 | config.AddConfig("Modules"); | 124 | config.AddConfig("Modules"); |
73 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 125 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
74 | 126 | ||
75 | scene = SceneHelpers.SetupScene(); | 127 | modules.Add(new AttachmentsModule()); |
76 | m_attMod = new AttachmentsModule(); | 128 | modules.Add(new BasicInventoryAccessModule()); |
77 | SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); | ||
78 | } | 129 | } |
79 | 130 | ||
80 | [TestFixtureTearDown] | 131 | private void AddScriptingConfig(IConfigSource config, List<object> modules) |
81 | public void TearDown() | ||
82 | { | 132 | { |
83 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | 133 | IConfig startupConfig = config.AddConfig("Startup"); |
84 | // threads. Possibly, later tests should be rewritten not to worry about such things. | 134 | startupConfig.Set("DefaultScriptEngine", "XEngine"); |
85 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | 135 | |
136 | IConfig xEngineConfig = config.AddConfig("XEngine"); | ||
137 | xEngineConfig.Set("Enabled", "true"); | ||
138 | xEngineConfig.Set("StartDelay", "0"); | ||
139 | |||
140 | // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call | ||
141 | // to AssemblyResolver.OnAssemblyResolve fails. | ||
142 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
143 | |||
144 | modules.Add(new XEngine()); | ||
145 | |||
146 | // Necessary to stop serialization complaining | ||
147 | // FIXME: Stop this being necessary if at all possible | ||
148 | // modules.Add(new WorldCommModule()); | ||
86 | } | 149 | } |
87 | 150 | ||
88 | /// <summary> | 151 | /// <summary> |
89 | /// Add the standard presence for a test. | 152 | /// Creates an attachment item in the given user's inventory. Does not attach. |
90 | /// </summary> | 153 | /// </summary> |
91 | private void AddPresence() | 154 | /// <remarks> |
155 | /// A user with the given ID and an inventory must already exist. | ||
156 | /// </remarks> | ||
157 | /// <returns> | ||
158 | /// The attachment item. | ||
159 | /// </returns> | ||
160 | /// <param name='scene'></param> | ||
161 | /// <param name='userId'></param> | ||
162 | /// <param name='attName'></param> | ||
163 | /// <param name='rawItemId'></param> | ||
164 | /// <param name='rawAssetId'></param> | ||
165 | private InventoryItemBase CreateAttachmentItem( | ||
166 | Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId) | ||
92 | { | 167 | { |
93 | UUID userId = TestHelpers.ParseTail(0x1); | 168 | return UserInventoryHelpers.CreateInventoryItem( |
94 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | 169 | scene, |
95 | m_presence = SceneHelpers.AddScenePresence(scene, userId); | 170 | attName, |
171 | TestHelpers.ParseTail(rawItemId), | ||
172 | TestHelpers.ParseTail(rawAssetId), | ||
173 | userId, | ||
174 | InventoryType.Object); | ||
96 | } | 175 | } |
97 | 176 | ||
98 | [Test] | 177 | [Test] |
99 | public void TestAddAttachmentFromGround() | 178 | public void TestAddAttachmentFromGround() |
100 | { | 179 | { |
101 | TestHelpers.InMethod(); | 180 | TestHelpers.InMethod(); |
102 | // log4net.Config.XmlConfigurator.Configure(); | 181 | // TestHelpers.EnableLogging(); |
182 | |||
183 | Scene scene = CreateTestScene(); | ||
184 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
185 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
103 | 186 | ||
104 | AddPresence(); | ||
105 | string attName = "att"; | 187 | string attName = "att"; |
106 | 188 | ||
107 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; | 189 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
108 | 190 | ||
109 | m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false, false); | 191 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); |
110 | 192 | ||
111 | // Check status on scene presence | 193 | // Check status on scene presence |
112 | Assert.That(m_presence.HasAttachments(), Is.True); | 194 | Assert.That(sp.HasAttachments(), Is.True); |
113 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 195 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
114 | Assert.That(attachments.Count, Is.EqualTo(1)); | 196 | Assert.That(attachments.Count, Is.EqualTo(1)); |
115 | SceneObjectGroup attSo = attachments[0]; | 197 | SceneObjectGroup attSo = attachments[0]; |
116 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 198 | Assert.That(attSo.Name, Is.EqualTo(attName)); |
@@ -121,42 +203,107 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
121 | 203 | ||
122 | // Check item status | 204 | // Check item status |
123 | Assert.That( | 205 | Assert.That( |
124 | m_presence.Appearance.GetAttachpoint(attSo.FromItemID), | 206 | sp.Appearance.GetAttachpoint(attSo.FromItemID), |
125 | Is.EqualTo((int)AttachmentPoint.Chest)); | 207 | Is.EqualTo((int)AttachmentPoint.Chest)); |
208 | |||
209 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
210 | Assert.That(attachmentItem, Is.Not.Null); | ||
211 | Assert.That(attachmentItem.Name, Is.EqualTo(attName)); | ||
212 | |||
213 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
214 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
215 | |||
216 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
217 | |||
218 | // TestHelpers.DisableLogging(); | ||
126 | } | 219 | } |
127 | 220 | ||
221 | /// <summary> | ||
222 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. | ||
223 | /// </summary> | ||
128 | [Test] | 224 | [Test] |
129 | public void TestAddAttachmentFromInventory() | 225 | public void TestAddSatOnAttachmentFromGround() |
130 | { | 226 | { |
131 | TestHelpers.InMethod(); | 227 | TestHelpers.InMethod(); |
132 | // log4net.Config.XmlConfigurator.Configure(); | 228 | // TestHelpers.EnableLogging(); |
133 | 229 | ||
134 | AddPresence(); | 230 | Scene scene = CreateTestScene(); |
231 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
232 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
135 | 233 | ||
136 | UUID attItemId = TestHelpers.ParseTail(0x2); | ||
137 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
138 | string attName = "att"; | 234 | string attName = "att"; |
139 | 235 | ||
140 | UserInventoryHelpers.CreateInventoryItem( | 236 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
141 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 237 | |
238 | UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2); | ||
239 | ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2); | ||
240 | |||
241 | // Put avatar within 10m of the prim so that sit doesn't fail. | ||
242 | sp2.AbsolutePosition = new Vector3(0, 0, 0); | ||
243 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); | ||
244 | |||
245 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); | ||
246 | |||
247 | Assert.That(sp.HasAttachments(), Is.False); | ||
248 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
249 | } | ||
250 | |||
251 | [Test] | ||
252 | public void TestRezAttachmentFromInventory() | ||
253 | { | ||
254 | TestHelpers.InMethod(); | ||
255 | // log4net.Config.XmlConfigurator.Configure(); | ||
256 | |||
257 | Scene scene = CreateTestScene(); | ||
258 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
259 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
142 | 260 | ||
143 | m_attMod.RezSingleAttachmentFromInventory( | 261 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
144 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | 262 | |
263 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
264 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
145 | 265 | ||
146 | // Check scene presence status | 266 | // Check scene presence status |
147 | Assert.That(m_presence.HasAttachments(), Is.True); | 267 | Assert.That(sp.HasAttachments(), Is.True); |
148 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 268 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
149 | Assert.That(attachments.Count, Is.EqualTo(1)); | 269 | Assert.That(attachments.Count, Is.EqualTo(1)); |
150 | SceneObjectGroup attSo = attachments[0]; | 270 | SceneObjectGroup attSo = attachments[0]; |
151 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 271 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
152 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 272 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
153 | Assert.That(attSo.IsAttachment); | 273 | Assert.That(attSo.IsAttachment); |
154 | Assert.That(attSo.UsesPhysics, Is.False); | 274 | Assert.That(attSo.UsesPhysics, Is.False); |
155 | Assert.That(attSo.IsTemporary, Is.False); | 275 | Assert.That(attSo.IsTemporary, Is.False); |
156 | 276 | ||
157 | // Check appearance status | 277 | // Check appearance status |
158 | Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); | 278 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); |
159 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | 279 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
280 | |||
281 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
282 | } | ||
283 | |||
284 | /// <summary> | ||
285 | /// Test specific conditions associated with rezzing a scripted attachment from inventory. | ||
286 | /// </summary> | ||
287 | [Test] | ||
288 | public void TestRezScriptedAttachmentFromInventory() | ||
289 | { | ||
290 | TestHelpers.InMethod(); | ||
291 | |||
292 | Scene scene = CreateTestScene(); | ||
293 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
294 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
295 | |||
296 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); | ||
297 | TaskInventoryHelpers.AddScript(scene, so.RootPart); | ||
298 | InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); | ||
299 | |||
300 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | ||
301 | |||
302 | // TODO: Need to have a test that checks the script is actually started but this involves a lot more | ||
303 | // plumbing of the script engine and either pausing for events or more infrastructure to turn off various | ||
304 | // script engine delays/asychronicity that isn't helpful in an automated regression testing context. | ||
305 | SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name); | ||
306 | Assert.That(attSo.ContainsScripts(), Is.True); | ||
160 | } | 307 | } |
161 | 308 | ||
162 | [Test] | 309 | [Test] |
@@ -165,29 +312,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
165 | TestHelpers.InMethod(); | 312 | TestHelpers.InMethod(); |
166 | // log4net.Config.XmlConfigurator.Configure(); | 313 | // log4net.Config.XmlConfigurator.Configure(); |
167 | 314 | ||
168 | AddPresence(); | 315 | Scene scene = CreateTestScene(); |
316 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
317 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
169 | 318 | ||
170 | UUID attItemId = TestHelpers.ParseTail(0x2); | 319 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
171 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
172 | string attName = "att"; | ||
173 | 320 | ||
174 | UserInventoryHelpers.CreateInventoryItem( | 321 | ISceneEntity so |
175 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 322 | = scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
176 | 323 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | |
177 | ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( | 324 | scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); |
178 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | ||
179 | m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); | ||
180 | 325 | ||
181 | // Check scene presence status | 326 | // Check scene presence status |
182 | Assert.That(m_presence.HasAttachments(), Is.False); | 327 | Assert.That(sp.HasAttachments(), Is.False); |
183 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 328 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
184 | Assert.That(attachments.Count, Is.EqualTo(0)); | 329 | Assert.That(attachments.Count, Is.EqualTo(0)); |
185 | 330 | ||
186 | // Check appearance status | 331 | // Check appearance status |
187 | Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); | 332 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0)); |
188 | 333 | ||
189 | // Check item status | 334 | // Check item status |
190 | Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); | 335 | Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); |
191 | 336 | ||
192 | // Check object in scene | 337 | // Check object in scene |
193 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); | 338 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); |
@@ -197,28 +342,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
197 | public void TestDetachAttachmentToInventory() | 342 | public void TestDetachAttachmentToInventory() |
198 | { | 343 | { |
199 | TestHelpers.InMethod(); | 344 | TestHelpers.InMethod(); |
200 | // log4net.Config.XmlConfigurator.Configure(); | ||
201 | 345 | ||
202 | AddPresence(); | 346 | Scene scene = CreateTestScene(); |
347 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
348 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
203 | 349 | ||
204 | UUID attItemId = TestHelpers.ParseTail(0x2); | 350 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
205 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
206 | string attName = "att"; | ||
207 | |||
208 | UserInventoryHelpers.CreateInventoryItem( | ||
209 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | ||
210 | 351 | ||
211 | m_attMod.RezSingleAttachmentFromInventory( | 352 | SceneObjectGroup so |
212 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | 353 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
213 | m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId); | 354 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
355 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); | ||
214 | 356 | ||
215 | // Check status on scene presence | 357 | // Check status on scene presence |
216 | Assert.That(m_presence.HasAttachments(), Is.False); | 358 | Assert.That(sp.HasAttachments(), Is.False); |
217 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 359 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
218 | Assert.That(attachments.Count, Is.EqualTo(0)); | 360 | Assert.That(attachments.Count, Is.EqualTo(0)); |
219 | 361 | ||
220 | // Check item status | 362 | // Check item status |
221 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); | 363 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); |
364 | |||
365 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); | ||
366 | } | ||
367 | |||
368 | /// <summary> | ||
369 | /// Test specific conditions associated with detaching a scripted attachment from inventory. | ||
370 | /// </summary> | ||
371 | [Test] | ||
372 | public void TestDetachScriptedAttachmentToInventory() | ||
373 | { | ||
374 | TestHelpers.InMethod(); | ||
375 | // TestHelpers.EnableLogging(); | ||
376 | |||
377 | Scene scene = CreateScriptingEnabledTestScene(); | ||
378 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
379 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
380 | |||
381 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); | ||
382 | TaskInventoryHelpers.AddScript(scene, so.RootPart); | ||
383 | InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); | ||
384 | |||
385 | // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running. | ||
386 | // In the future, we need to be able to do this programatically more predicably. | ||
387 | scene.EventManager.OnChatFromWorld += OnChatFromWorld; | ||
388 | |||
389 | SceneObjectGroup soRezzed | ||
390 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | ||
391 | |||
392 | // Wait for chat to signal rezzed script has been started. | ||
393 | m_chatEvent.WaitOne(60000); | ||
394 | |||
395 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed); | ||
396 | |||
397 | InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem); | ||
398 | AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString()); | ||
399 | |||
400 | XmlDocument soXml = new XmlDocument(); | ||
401 | soXml.LoadXml(Encoding.UTF8.GetString(asset.Data)); | ||
402 | |||
403 | XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState"); | ||
404 | Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); | ||
222 | } | 405 | } |
223 | 406 | ||
224 | /// <summary> | 407 | /// <summary> |
@@ -230,17 +413,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
230 | TestHelpers.InMethod(); | 413 | TestHelpers.InMethod(); |
231 | // log4net.Config.XmlConfigurator.Configure(); | 414 | // log4net.Config.XmlConfigurator.Configure(); |
232 | 415 | ||
233 | UUID userId = TestHelpers.ParseTail(0x1); | 416 | Scene scene = CreateTestScene(); |
234 | UUID attItemId = TestHelpers.ParseTail(0x2); | 417 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
235 | UUID attAssetId = TestHelpers.ParseTail(0x3); | 418 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
236 | string attName = "att"; | ||
237 | |||
238 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | ||
239 | InventoryItemBase attItem | ||
240 | = UserInventoryHelpers.CreateInventoryItem( | ||
241 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
242 | 419 | ||
243 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | 420 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
244 | acd.Appearance = new AvatarAppearance(); | 421 | acd.Appearance = new AvatarAppearance(); |
245 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | 422 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); |
246 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | 423 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); |
@@ -259,17 +436,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
259 | TestHelpers.InMethod(); | 436 | TestHelpers.InMethod(); |
260 | // log4net.Config.XmlConfigurator.Configure(); | 437 | // log4net.Config.XmlConfigurator.Configure(); |
261 | 438 | ||
262 | UUID userId = TestHelpers.ParseTail(0x1); | 439 | Scene scene = CreateTestScene(); |
263 | UUID attItemId = TestHelpers.ParseTail(0x2); | 440 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
264 | UUID attAssetId = TestHelpers.ParseTail(0x3); | 441 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
265 | string attName = "att"; | ||
266 | 442 | ||
267 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | 443 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
268 | InventoryItemBase attItem | ||
269 | = UserInventoryHelpers.CreateInventoryItem( | ||
270 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
271 | |||
272 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | ||
273 | acd.Appearance = new AvatarAppearance(); | 444 | acd.Appearance = new AvatarAppearance(); |
274 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | 445 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); |
275 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | 446 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); |
@@ -279,7 +450,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
279 | 450 | ||
280 | Assert.That(attachments.Count, Is.EqualTo(1)); | 451 | Assert.That(attachments.Count, Is.EqualTo(1)); |
281 | SceneObjectGroup attSo = attachments[0]; | 452 | SceneObjectGroup attSo = attachments[0]; |
282 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 453 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
283 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 454 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
284 | Assert.That(attSo.IsAttachment); | 455 | Assert.That(attSo.IsAttachment); |
285 | Assert.That(attSo.UsesPhysics, Is.False); | 456 | Assert.That(attSo.UsesPhysics, Is.False); |
@@ -289,9 +460,125 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
289 | List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); | 460 | List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); |
290 | Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); | 461 | Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); |
291 | Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | 462 | Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); |
292 | Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId)); | 463 | Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID)); |
293 | Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId)); | 464 | Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); |
294 | Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | 465 | Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
466 | |||
467 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
468 | } | ||
469 | |||
470 | [Test] | ||
471 | public void TestUpdateAttachmentPosition() | ||
472 | { | ||
473 | TestHelpers.InMethod(); | ||
474 | |||
475 | Scene scene = CreateTestScene(); | ||
476 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
477 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | ||
478 | |||
479 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | ||
480 | acd.Appearance = new AvatarAppearance(); | ||
481 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | ||
482 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); | ||
483 | |||
484 | SceneObjectGroup attSo = sp.GetAttachments()[0]; | ||
485 | |||
486 | Vector3 newPosition = new Vector3(1, 2, 4); | ||
487 | |||
488 | scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); | ||
489 | |||
490 | Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); | ||
491 | Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); | ||
492 | } | ||
493 | |||
494 | [Test] | ||
495 | public void TestSameSimulatorNeighbouringRegionsTeleport() | ||
496 | { | ||
497 | TestHelpers.InMethod(); | ||
498 | // TestHelpers.EnableLogging(); | ||
499 | |||
500 | AttachmentsModule attModA = new AttachmentsModule(); | ||
501 | AttachmentsModule attModB = new AttachmentsModule(); | ||
502 | EntityTransferModule etmA = new EntityTransferModule(); | ||
503 | EntityTransferModule etmB = new EntityTransferModule(); | ||
504 | LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); | ||
505 | |||
506 | IConfigSource config = new IniConfigSource(); | ||
507 | IConfig modulesConfig = config.AddConfig("Modules"); | ||
508 | modulesConfig.Set("EntityTransferModule", etmA.Name); | ||
509 | modulesConfig.Set("SimulationServices", lscm.Name); | ||
510 | IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); | ||
511 | |||
512 | // In order to run a single threaded regression test we do not want the entity transfer module waiting | ||
513 | // for a callback from the destination scene before removing its avatar data. | ||
514 | entityTransferConfig.Set("wait_for_callback", false); | ||
515 | |||
516 | modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); | ||
517 | |||
518 | SceneHelpers sh = new SceneHelpers(); | ||
519 | TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); | ||
520 | TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); | ||
521 | |||
522 | SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); | ||
523 | SceneHelpers.SetupSceneModules( | ||
524 | sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); | ||
525 | SceneHelpers.SetupSceneModules( | ||
526 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | ||
527 | |||
528 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | ||
529 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); | ||
530 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | ||
531 | |||
532 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | ||
533 | |||
534 | sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
535 | beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
536 | |||
537 | Vector3 teleportPosition = new Vector3(10, 11, 12); | ||
538 | Vector3 teleportLookAt = new Vector3(20, 21, 22); | ||
539 | |||
540 | sceneA.RequestTeleportLocation( | ||
541 | beforeTeleportSp.ControllingClient, | ||
542 | sceneB.RegionInfo.RegionHandle, | ||
543 | teleportPosition, | ||
544 | teleportLookAt, | ||
545 | (uint)TeleportFlags.ViaLocation); | ||
546 | |||
547 | ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); | ||
548 | |||
549 | // Check attachments have made it into sceneB | ||
550 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); | ||
551 | |||
552 | // This is appearance data, as opposed to actually rezzed attachments | ||
553 | List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); | ||
554 | Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); | ||
555 | Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | ||
556 | Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); | ||
557 | Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); | ||
558 | Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
559 | |||
560 | // This is the actual attachment | ||
561 | List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); | ||
562 | Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); | ||
563 | SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; | ||
564 | Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); | ||
565 | Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); | ||
566 | |||
567 | Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
568 | |||
569 | // Check attachments have been removed from sceneA | ||
570 | ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); | ||
571 | |||
572 | // Since this is appearance data, it is still present on the child avatar! | ||
573 | List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); | ||
574 | Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); | ||
575 | Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
576 | |||
577 | // This is the actual attachment, which should no longer exist | ||
578 | List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); | ||
579 | Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); | ||
580 | |||
581 | Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); | ||
295 | } | 582 | } |
296 | 583 | ||
297 | // I'm commenting this test because scene setup NEEDS InventoryService to | 584 | // I'm commenting this test because scene setup NEEDS InventoryService to |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 2bebd30..89cc4f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -128,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
128 | /// <param name="visualParam"></param> | 128 | /// <param name="visualParam"></param> |
129 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) | 129 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) |
130 | { | 130 | { |
131 | // m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); | 131 | // m_log.DebugFormat( |
132 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | ||
133 | // sp.Name, textureEntry, visualParams); | ||
132 | 134 | ||
133 | // TODO: This is probably not necessary any longer, just assume the | 135 | // TODO: This is probably not necessary any longer, just assume the |
134 | // textureEntry set implies that the appearance transaction is complete | 136 | // textureEntry set implies that the appearance transaction is complete |
@@ -158,7 +160,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
158 | // Process the baked texture array | 160 | // Process the baked texture array |
159 | if (textureEntry != null) | 161 | if (textureEntry != null) |
160 | { | 162 | { |
161 | m_log.InfoFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); | 163 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); |
162 | 164 | ||
163 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 165 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
164 | 166 | ||
@@ -208,7 +210,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
208 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 210 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
209 | if (sp == null) | 211 | if (sp == null) |
210 | { | 212 | { |
211 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | 213 | // This is expected if the user has gone away. |
214 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | ||
212 | return false; | 215 | return false; |
213 | } | 216 | } |
214 | 217 | ||
@@ -248,10 +251,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
248 | 251 | ||
249 | if (bakedTextureFace == null) | 252 | if (bakedTextureFace == null) |
250 | { | 253 | { |
251 | m_log.WarnFormat( | 254 | // This can happen legitimately, since some baked textures might not exist |
252 | "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", | 255 | //m_log.WarnFormat( |
253 | bakeType, sp.Name, m_scene.RegionInfo.RegionName); | 256 | // "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", |
254 | 257 | // bakeType, sp.Name, m_scene.RegionInfo.RegionName); | |
255 | continue; | 258 | continue; |
256 | } | 259 | } |
257 | 260 | ||
@@ -337,7 +340,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
337 | return false; | 340 | return false; |
338 | } | 341 | } |
339 | 342 | ||
340 | m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 343 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); |
341 | 344 | ||
342 | // If we only found default textures, then the appearance is not cached | 345 | // If we only found default textures, then the appearance is not cached |
343 | return (defonly ? false : true); | 346 | return (defonly ? false : true); |
@@ -370,11 +373,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
370 | if (missingTexturesOnly) | 373 | if (missingTexturesOnly) |
371 | { | 374 | { |
372 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) | 375 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) |
376 | { | ||
373 | continue; | 377 | continue; |
378 | } | ||
374 | else | 379 | else |
380 | { | ||
381 | // On inter-simulator teleports, this occurs if baked textures are not being stored by the | ||
382 | // grid asset service (which means that they are not available to the new region and so have | ||
383 | // to be re-requested from the client). | ||
384 | // | ||
385 | // The only available core OpenSimulator behaviour right now | ||
386 | // is not to store these textures, temporarily or otherwise. | ||
375 | m_log.DebugFormat( | 387 | m_log.DebugFormat( |
376 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | 388 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", |
377 | face.TextureID, idx, sp.Name); | 389 | face.TextureID, idx, sp.Name); |
390 | } | ||
378 | } | 391 | } |
379 | else | 392 | else |
380 | { | 393 | { |
@@ -417,7 +430,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
417 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | 430 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); |
418 | 431 | ||
419 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); | 432 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); |
420 | bakedTextures[bakeType] = faceTextures[ftIndex]; | 433 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture |
434 | bakedTextures[bakeType] = texture; | ||
421 | } | 435 | } |
422 | 436 | ||
423 | return bakedTextures; | 437 | return bakedTextures; |
@@ -482,7 +496,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
482 | ScenePresence sp = m_scene.GetScenePresence(agentid); | 496 | ScenePresence sp = m_scene.GetScenePresence(agentid); |
483 | if (sp == null) | 497 | if (sp == null) |
484 | { | 498 | { |
485 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | 499 | // This is expected if the user has gone away. |
500 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | ||
486 | return; | 501 | return; |
487 | } | 502 | } |
488 | 503 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 11a0a86..848b3bf 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | |||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
53 | UUID userId = TestHelpers.ParseTail(0x1); | 53 | UUID userId = TestHelpers.ParseTail(0x1); |
54 | 54 | ||
55 | AvatarFactoryModule afm = new AvatarFactoryModule(); | 55 | AvatarFactoryModule afm = new AvatarFactoryModule(); |
56 | TestScene scene = SceneHelpers.SetupScene(); | 56 | TestScene scene = new SceneHelpers().SetupScene(); |
57 | SceneHelpers.SetupSceneModules(scene, afm); | 57 | SceneHelpers.SetupSceneModules(scene, afm); |
58 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); | 58 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); |
59 | 59 | ||
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
81 | CoreAssetCache assetCache = new CoreAssetCache(); | 81 | CoreAssetCache assetCache = new CoreAssetCache(); |
82 | 82 | ||
83 | AvatarFactoryModule afm = new AvatarFactoryModule(); | 83 | AvatarFactoryModule afm = new AvatarFactoryModule(); |
84 | TestScene scene = SceneHelpers.SetupScene(assetCache); | 84 | TestScene scene = new SceneHelpers(assetCache).SetupScene(); |
85 | SceneHelpers.SetupSceneModules(scene, afm); | 85 | SceneHelpers.SetupSceneModules(scene, afm); |
86 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); | 86 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); |
87 | 87 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 6215526..dbbb0ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -266,7 +266,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
266 | receiverIDs.Add(presence.UUID); | 266 | receiverIDs.Add(presence.UUID); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | |||
270 | } | 269 | } |
271 | ); | 270 | ); |
272 | } | 271 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 0babeb5..3a91465 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs | |||
@@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
96 | ScenePresence killingAvatar = null; | 96 | ScenePresence killingAvatar = null; |
97 | // string killingAvatarMessage; | 97 | // string killingAvatarMessage; |
98 | 98 | ||
99 | // check to see if it is an NPC and just remove it | ||
100 | INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface<INPCModule>(); | ||
101 | if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene)) | ||
102 | { | ||
103 | return; | ||
104 | } | ||
105 | |||
99 | if (killerObjectLocalID == 0) | 106 | if (killerObjectLocalID == 0) |
100 | deadAvatarMessage = "You committed suicide!"; | 107 | deadAvatarMessage = "You committed suicide!"; |
101 | else | 108 | else |
@@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
145 | catch (InvalidOperationException) | 152 | catch (InvalidOperationException) |
146 | { } | 153 | { } |
147 | 154 | ||
148 | deadAvatar.Health = 100; | 155 | deadAvatar.setHealthWithUpdate(100.0f); |
149 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); | 156 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); |
150 | } | 157 | } |
151 | 158 | ||
@@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
154 | try | 161 | try |
155 | { | 162 | { |
156 | ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 163 | ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
157 | 164 | if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 | |
158 | if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) | 165 | || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) |
159 | { | 166 | { |
160 | avatar.Invulnerable = false; | 167 | avatar.Invulnerable = false; |
161 | } | 168 | } |
162 | else | 169 | else |
163 | { | 170 | { |
164 | avatar.Invulnerable = true; | 171 | avatar.Invulnerable = true; |
172 | if (avatar.Health < 100.0f) | ||
173 | { | ||
174 | avatar.setHealthWithUpdate(100.0f); | ||
175 | } | ||
165 | } | 176 | } |
166 | } | 177 | } |
167 | catch (Exception) | 178 | catch (Exception) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs new file mode 100644 index 0000000..4bcd2ac --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Text.RegularExpressions; | ||
33 | using log4net; | ||
34 | using Mono.Addins; | ||
35 | using NDesk.Options; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Statistics; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.CoreModules.Avatars.Commands | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that holds commands for manipulating objects in the scene. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserCommandsModule")] | ||
50 | public class UserCommandsModule : ISharedRegionModule | ||
51 | { | ||
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | public const string TeleportUserCommandSyntax = "teleport user <first-name> <last-name> <destination>"; | ||
55 | |||
56 | public static Regex InterRegionDestinationRegex | ||
57 | = new Regex(@"^(?<regionName>.+)/(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
58 | |||
59 | public static Regex WithinRegionDestinationRegex | ||
60 | = new Regex(@"^(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
61 | |||
62 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||
63 | |||
64 | public string Name { get { return "User Commands Module"; } } | ||
65 | |||
66 | public Type ReplaceableInterface { get { return null; } } | ||
67 | |||
68 | public void Initialise(IConfigSource source) | ||
69 | { | ||
70 | // m_log.DebugFormat("[USER COMMANDS MODULE]: INITIALIZED MODULE"); | ||
71 | } | ||
72 | |||
73 | public void PostInitialise() | ||
74 | { | ||
75 | // m_log.DebugFormat("[USER COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
76 | } | ||
77 | |||
78 | public void Close() | ||
79 | { | ||
80 | // m_log.DebugFormat("[USER COMMANDS MODULE]: CLOSED MODULE"); | ||
81 | } | ||
82 | |||
83 | public void AddRegion(Scene scene) | ||
84 | { | ||
85 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
86 | |||
87 | lock (m_scenes) | ||
88 | m_scenes[scene.RegionInfo.RegionID] = scene; | ||
89 | |||
90 | scene.AddCommand( | ||
91 | "Users", | ||
92 | this, | ||
93 | "teleport user", | ||
94 | TeleportUserCommandSyntax, | ||
95 | "Teleport a user in this simulator to the given destination", | ||
96 | "<destination> is in format [<region-name>]/<x>/<y>/<z>, e.g. regionone/20/30/40 or just 20/30/40 to teleport within same region." | ||
97 | + "\nIf the region contains a space then the whole destination must be in quotes, e.g. \"region one/20/30/40\"", | ||
98 | HandleTeleportUser); | ||
99 | } | ||
100 | |||
101 | public void RemoveRegion(Scene scene) | ||
102 | { | ||
103 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
104 | |||
105 | lock (m_scenes) | ||
106 | m_scenes.Remove(scene.RegionInfo.RegionID); | ||
107 | } | ||
108 | |||
109 | public void RegionLoaded(Scene scene) | ||
110 | { | ||
111 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
112 | } | ||
113 | |||
114 | private ScenePresence GetUser(string firstName, string lastName) | ||
115 | { | ||
116 | ScenePresence userFound = null; | ||
117 | |||
118 | lock (m_scenes) | ||
119 | { | ||
120 | foreach (Scene scene in m_scenes.Values) | ||
121 | { | ||
122 | ScenePresence user = scene.GetScenePresence(firstName, lastName); | ||
123 | if (user != null && !user.IsChildAgent) | ||
124 | { | ||
125 | userFound = user; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return userFound; | ||
132 | } | ||
133 | |||
134 | private void HandleTeleportUser(string module, string[] cmd) | ||
135 | { | ||
136 | if (cmd.Length < 5) | ||
137 | { | ||
138 | MainConsole.Instance.OutputFormat("Usage: " + TeleportUserCommandSyntax); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | string firstName = cmd[2]; | ||
143 | string lastName = cmd[3]; | ||
144 | string rawDestination = cmd[4]; | ||
145 | |||
146 | ScenePresence user = GetUser(firstName, lastName); | ||
147 | |||
148 | if (user == null) | ||
149 | { | ||
150 | MainConsole.Instance.OutputFormat("No user found with name {0} {1}", firstName, lastName); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | // MainConsole.Instance.OutputFormat("rawDestination [{0}]", rawDestination); | ||
155 | |||
156 | Match m = WithinRegionDestinationRegex.Match(rawDestination); | ||
157 | |||
158 | if (!m.Success) | ||
159 | { | ||
160 | m = InterRegionDestinationRegex.Match(rawDestination); | ||
161 | |||
162 | if (!m.Success) | ||
163 | { | ||
164 | MainConsole.Instance.OutputFormat("Invalid destination {0}", rawDestination); | ||
165 | return; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | string regionName | ||
170 | = m.Groups["regionName"].Success ? m.Groups["regionName"].Value : user.Scene.RegionInfo.RegionName; | ||
171 | |||
172 | MainConsole.Instance.OutputFormat( | ||
173 | "Teleporting {0} to {1},{2},{3} in {4}", | ||
174 | user.Name, | ||
175 | m.Groups["x"], m.Groups["y"], m.Groups["z"], | ||
176 | regionName); | ||
177 | |||
178 | user.Scene.RequestTeleportLocation( | ||
179 | user.ControllingClient, | ||
180 | regionName, | ||
181 | new Vector3( | ||
182 | float.Parse(m.Groups["x"].Value), | ||
183 | float.Parse(m.Groups["y"].Value), | ||
184 | float.Parse(m.Groups["z"].Value)), | ||
185 | user.Lookat, | ||
186 | (uint)TeleportFlags.ViaLocation); | ||
187 | } | ||
188 | } | ||
189 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index f64c161..24ec435 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | protected void InitModule(IConfigSource config) | 165 | protected virtual void InitModule(IConfigSource config) |
166 | { | 166 | { |
167 | IConfig friendsConfig = config.Configs["Friends"]; | 167 | IConfig friendsConfig = config.Configs["Friends"]; |
168 | if (friendsConfig != null) | 168 | if (friendsConfig != null) |
@@ -449,29 +449,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
449 | /// </summary> | 449 | /// </summary> |
450 | public IClientAPI LocateClientObject(UUID agentID) | 450 | public IClientAPI LocateClientObject(UUID agentID) |
451 | { | 451 | { |
452 | Scene scene = GetClientScene(agentID); | ||
453 | if (scene != null) | ||
454 | { | ||
455 | ScenePresence presence = scene.GetScenePresence(agentID); | ||
456 | if (presence != null) | ||
457 | return presence.ControllingClient; | ||
458 | } | ||
459 | |||
460 | return null; | ||
461 | } | ||
462 | |||
463 | /// <summary> | ||
464 | /// Find the scene for an agent | ||
465 | /// </summary> | ||
466 | private Scene GetClientScene(UUID agentId) | ||
467 | { | ||
468 | lock (m_Scenes) | 452 | lock (m_Scenes) |
469 | { | 453 | { |
470 | foreach (Scene scene in m_Scenes) | 454 | foreach (Scene scene in m_Scenes) |
471 | { | 455 | { |
472 | ScenePresence presence = scene.GetScenePresence(agentId); | 456 | ScenePresence presence = scene.GetScenePresence(agentID); |
473 | if (presence != null && !presence.IsChildAgent) | 457 | if (presence != null && !presence.IsChildAgent) |
474 | return scene; | 458 | return presence.ControllingClient; |
475 | } | 459 | } |
476 | } | 460 | } |
477 | 461 | ||
@@ -498,7 +482,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
498 | Util.FireAndForget( | 482 | Util.FireAndForget( |
499 | delegate | 483 | delegate |
500 | { | 484 | { |
501 | m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count); | 485 | m_log.DebugFormat( |
486 | "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", | ||
487 | friendList.Count, agentID, online); | ||
488 | |||
502 | // Notify about this user status | 489 | // Notify about this user status |
503 | StatusNotify(friendList, agentID, online); | 490 | StatusNotify(friendList, agentID, online); |
504 | } | 491 | } |
@@ -515,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
515 | { | 502 | { |
516 | // Try local | 503 | // Try local |
517 | if (LocalStatusNotification(userID, friendID, online)) | 504 | if (LocalStatusNotification(userID, friendID, online)) |
518 | return; | 505 | continue; |
519 | 506 | ||
520 | // The friend is not here [as root]. Let's forward. | 507 | // The friend is not here [as root]. Let's forward. |
521 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); | 508 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); |
@@ -523,11 +510,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
523 | { | 510 | { |
524 | PresenceInfo friendSession = null; | 511 | PresenceInfo friendSession = null; |
525 | foreach (PresenceInfo pinfo in friendSessions) | 512 | foreach (PresenceInfo pinfo in friendSessions) |
513 | { | ||
526 | if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad | 514 | if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad |
527 | { | 515 | { |
528 | friendSession = pinfo; | 516 | friendSession = pinfo; |
529 | break; | 517 | break; |
530 | } | 518 | } |
519 | } | ||
531 | 520 | ||
532 | if (friendSession != null) | 521 | if (friendSession != null) |
533 | { | 522 | { |
@@ -546,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
546 | } | 535 | } |
547 | } | 536 | } |
548 | 537 | ||
549 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 538 | protected virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
550 | { | 539 | { |
551 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) | 540 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) |
552 | { | 541 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 9a6d277..06f27e2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
50 | { | 50 | { |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | private int m_levelHGFriends = 0; | ||
54 | |||
53 | IUserManagement m_uMan; | 55 | IUserManagement m_uMan; |
54 | public IUserManagement UserManagementModule | 56 | public IUserManagement UserManagementModule |
55 | { | 57 | { |
@@ -87,6 +89,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
87 | m_StatusNotifier = new HGStatusNotifier(this); | 89 | m_StatusNotifier = new HGStatusNotifier(this); |
88 | } | 90 | } |
89 | 91 | ||
92 | protected override void InitModule(IConfigSource config) | ||
93 | { | ||
94 | base.InitModule(config); | ||
95 | |||
96 | // Additionally to the base method | ||
97 | IConfig friendsConfig = config.Configs["HGFriendsModule"]; | ||
98 | if (friendsConfig != null) | ||
99 | { | ||
100 | m_levelHGFriends = friendsConfig.GetInt("LevelHGFriends", 0); | ||
101 | |||
102 | // TODO: read in all config variables pertaining to | ||
103 | // HG friendship permissions | ||
104 | } | ||
105 | } | ||
106 | |||
90 | #endregion | 107 | #endregion |
91 | 108 | ||
92 | #region IFriendsSimConnector | 109 | #region IFriendsSimConnector |
@@ -105,6 +122,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
105 | 122 | ||
106 | #endregion | 123 | #endregion |
107 | 124 | ||
125 | protected override void OnInstantMessage(IClientAPI client, GridInstantMessage im) | ||
126 | { | ||
127 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) | ||
128 | { | ||
129 | // we got a friendship offer | ||
130 | UUID principalID = new UUID(im.fromAgentID); | ||
131 | UUID friendID = new UUID(im.toAgentID); | ||
132 | |||
133 | // Check if friendID is foreigner and if principalID has the permission | ||
134 | // to request friendships with foreigners. If not, return immediately. | ||
135 | if (!UserManagementModule.IsLocalGridUser(friendID)) | ||
136 | { | ||
137 | ScenePresence avatar = null; | ||
138 | ((Scene)client.Scene).TryGetScenePresence(principalID, out avatar); | ||
139 | |||
140 | if (avatar == null) | ||
141 | return; | ||
142 | |||
143 | if (avatar.UserLevel < m_levelHGFriends) | ||
144 | { | ||
145 | client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false); | ||
146 | return; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | base.OnInstantMessage(client, im); | ||
152 | } | ||
153 | |||
108 | protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) | 154 | protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) |
109 | { | 155 | { |
110 | // Update the local cache. Yes, we need to do it right here | 156 | // Update the local cache. Yes, we need to do it right here |
@@ -369,12 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
369 | 415 | ||
370 | protected override void StoreBackwards(UUID friendID, UUID agentID) | 416 | protected override void StoreBackwards(UUID friendID, UUID agentID) |
371 | { | 417 | { |
372 | Boolean agentIsLocal = true; | 418 | bool agentIsLocal = true; |
373 | Boolean friendIsLocal = true; | 419 | // bool friendIsLocal = true; |
420 | |||
374 | if (UserManagementModule != null) | 421 | if (UserManagementModule != null) |
375 | { | 422 | { |
376 | agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); | 423 | agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); |
377 | friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); | 424 | // friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); |
378 | } | 425 | } |
379 | 426 | ||
380 | // Is the requester a local user? | 427 | // Is the requester a local user? |
@@ -461,7 +508,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
461 | { | 508 | { |
462 | friendUUI = finfo.Friend; | 509 | friendUUI = finfo.Friend; |
463 | theFriendUUID = friendUUI; | 510 | theFriendUUID = friendUUI; |
464 | UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; | 511 | UUID utmp = UUID.Zero; |
512 | string url = String.Empty; | ||
513 | string first = String.Empty; | ||
514 | string last = String.Empty; | ||
515 | |||
465 | // If it's confirming the friendship, we already have the full UUI with the secret | 516 | // If it's confirming the friendship, we already have the full UUI with the secret |
466 | if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) | 517 | if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) |
467 | { | 518 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 45b4264..7a197f7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | |||
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | |||
78 | config.AddConfig("FriendsService"); | 78 | config.AddConfig("FriendsService"); |
79 | config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); | 79 | config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); |
80 | 80 | ||
81 | m_scene = SceneHelpers.SetupScene(); | 81 | m_scene = new SceneHelpers().SetupScene(); |
82 | m_fm = new FriendsModule(); | 82 | m_fm = new FriendsModule(); |
83 | SceneHelpers.SetupSceneModules(m_scene, config, m_fm); | 83 | SceneHelpers.SetupSceneModules(m_scene, config, m_fm); |
84 | } | 84 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 8560c73..6587ead 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -39,6 +39,9 @@ using OpenSim.Framework.Serialization.External; | |||
39 | using OpenSim.Region.CoreModules.World.Archiver; | 39 | using OpenSim.Region.CoreModules.World.Archiver; |
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using Ionic.Zlib; | ||
43 | using GZipStream = Ionic.Zlib.GZipStream; | ||
44 | using CompressionMode = Ionic.Zlib.CompressionMode; | ||
42 | 45 | ||
43 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | 46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver |
44 | { | 47 | { |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | /// Constructor | 94 | /// Constructor |
92 | /// </summary> | 95 | /// </summary> |
93 | public InventoryArchiveWriteRequest( | 96 | public InventoryArchiveWriteRequest( |
94 | Guid id, InventoryArchiverModule module, Scene scene, | 97 | Guid id, InventoryArchiverModule module, Scene scene, |
95 | UserAccount userInfo, string invPath, string savePath) | 98 | UserAccount userInfo, string invPath, string savePath) |
96 | : this( | 99 | : this( |
97 | id, | 100 | id, |
@@ -99,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
99 | scene, | 102 | scene, |
100 | userInfo, | 103 | userInfo, |
101 | invPath, | 104 | invPath, |
102 | new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress)) | 105 | new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression)) |
103 | { | 106 | { |
104 | } | 107 | } |
105 | 108 | ||
@@ -107,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
107 | /// Constructor | 110 | /// Constructor |
108 | /// </summary> | 111 | /// </summary> |
109 | public InventoryArchiveWriteRequest( | 112 | public InventoryArchiveWriteRequest( |
110 | Guid id, InventoryArchiverModule module, Scene scene, | 113 | Guid id, InventoryArchiverModule module, Scene scene, |
111 | UserAccount userInfo, string invPath, Stream saveStream) | 114 | UserAccount userInfo, string invPath, Stream saveStream) |
112 | { | 115 | { |
113 | m_id = id; | 116 | m_id = id; |
@@ -125,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
125 | { | 128 | { |
126 | Exception reportedException = null; | 129 | Exception reportedException = null; |
127 | bool succeeded = true; | 130 | bool succeeded = true; |
128 | 131 | ||
129 | try | 132 | try |
130 | { | 133 | { |
131 | m_archiveWriter.Close(); | 134 | m_archiveWriter.Close(); |
@@ -146,6 +149,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
146 | 149 | ||
147 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) | 150 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) |
148 | { | 151 | { |
152 | if (options.ContainsKey("exclude")) | ||
153 | { | ||
154 | if (((List<String>)options["exclude"]).Contains(inventoryItem.Name) || | ||
155 | ((List<String>)options["exclude"]).Contains(inventoryItem.ID.ToString())) | ||
156 | { | ||
157 | if (options.ContainsKey("verbose")) | ||
158 | { | ||
159 | m_log.InfoFormat( | ||
160 | "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", | ||
161 | inventoryItem.Name, inventoryItem.ID, path); | ||
162 | } | ||
163 | return; | ||
164 | } | ||
165 | } | ||
166 | |||
149 | if (options.ContainsKey("verbose")) | 167 | if (options.ContainsKey("verbose")) |
150 | m_log.InfoFormat( | 168 | m_log.InfoFormat( |
151 | "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", | 169 | "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", |
@@ -175,9 +193,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
175 | /// <param name="options"></param> | 193 | /// <param name="options"></param> |
176 | /// <param name="userAccountService"></param> | 194 | /// <param name="userAccountService"></param> |
177 | protected void SaveInvFolder( | 195 | protected void SaveInvFolder( |
178 | InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, | 196 | InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, |
179 | Dictionary<string, object> options, IUserAccountService userAccountService) | 197 | Dictionary<string, object> options, IUserAccountService userAccountService) |
180 | { | 198 | { |
199 | if (options.ContainsKey("excludefolders")) | ||
200 | { | ||
201 | if (((List<String>)options["excludefolders"]).Contains(inventoryFolder.Name) || | ||
202 | ((List<String>)options["excludefolders"]).Contains(inventoryFolder.ID.ToString())) | ||
203 | { | ||
204 | if (options.ContainsKey("verbose")) | ||
205 | { | ||
206 | m_log.InfoFormat( | ||
207 | "[INVENTORY ARCHIVER]: Skipping folder {0} at {1}", | ||
208 | inventoryFolder.Name, path); | ||
209 | } | ||
210 | return; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | if (options.ContainsKey("verbose")) | ||
215 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name); | ||
216 | |||
181 | if (saveThisFolderItself) | 217 | if (saveThisFolderItself) |
182 | { | 218 | { |
183 | path += CreateArchiveFolderName(inventoryFolder); | 219 | path += CreateArchiveFolderName(inventoryFolder); |
@@ -186,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
186 | m_archiveWriter.WriteDir(path); | 222 | m_archiveWriter.WriteDir(path); |
187 | } | 223 | } |
188 | 224 | ||
189 | InventoryCollection contents | 225 | InventoryCollection contents |
190 | = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); | 226 | = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); |
191 | 227 | ||
192 | foreach (InventoryFolderBase childFolder in contents.Folders) | 228 | foreach (InventoryFolderBase childFolder in contents.Folders) |
@@ -213,16 +249,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
213 | InventoryFolderBase inventoryFolder = null; | 249 | InventoryFolderBase inventoryFolder = null; |
214 | InventoryItemBase inventoryItem = null; | 250 | InventoryItemBase inventoryItem = null; |
215 | InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); | 251 | InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); |
216 | 252 | ||
217 | bool saveFolderContentsOnly = false; | 253 | bool saveFolderContentsOnly = false; |
218 | 254 | ||
219 | // Eliminate double slashes and any leading / on the path. | 255 | // Eliminate double slashes and any leading / on the path. |
220 | string[] components | 256 | string[] components |
221 | = m_invPath.Split( | 257 | = m_invPath.Split( |
222 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); | 258 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); |
223 | 259 | ||
224 | int maxComponentIndex = components.Length - 1; | 260 | int maxComponentIndex = components.Length - 1; |
225 | 261 | ||
226 | // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the | 262 | // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the |
227 | // folder itself. This may get more sophisicated later on | 263 | // folder itself. This may get more sophisicated later on |
228 | if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) | 264 | if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) |
@@ -230,13 +266,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
230 | saveFolderContentsOnly = true; | 266 | saveFolderContentsOnly = true; |
231 | maxComponentIndex--; | 267 | maxComponentIndex--; |
232 | } | 268 | } |
233 | 269 | ||
234 | m_invPath = String.Empty; | 270 | m_invPath = String.Empty; |
235 | for (int i = 0; i <= maxComponentIndex; i++) | 271 | for (int i = 0; i <= maxComponentIndex; i++) |
236 | { | 272 | { |
237 | m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; | 273 | m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; |
238 | } | 274 | } |
239 | 275 | ||
240 | // Annoyingly Split actually returns the original string if the input string consists only of delimiters | 276 | // Annoyingly Split actually returns the original string if the input string consists only of delimiters |
241 | // Therefore if we still start with a / after the split, then we need the root folder | 277 | // Therefore if we still start with a / after the split, then we need the root folder |
242 | if (m_invPath.Length == 0) | 278 | if (m_invPath.Length == 0) |
@@ -246,25 +282,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
246 | else | 282 | else |
247 | { | 283 | { |
248 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); | 284 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); |
249 | List<InventoryFolderBase> candidateFolders | 285 | List<InventoryFolderBase> candidateFolders |
250 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); | 286 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); |
251 | if (candidateFolders.Count > 0) | 287 | if (candidateFolders.Count > 0) |
252 | inventoryFolder = candidateFolders[0]; | 288 | inventoryFolder = candidateFolders[0]; |
253 | } | 289 | } |
254 | 290 | ||
255 | // The path may point to an item instead | 291 | // The path may point to an item instead |
256 | if (inventoryFolder == null) | 292 | if (inventoryFolder == null) |
257 | inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); | 293 | inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); |
258 | 294 | ||
259 | if (null == inventoryFolder && null == inventoryItem) | 295 | if (null == inventoryFolder && null == inventoryItem) |
260 | { | 296 | { |
261 | // We couldn't find the path indicated | 297 | // We couldn't find the path indicated |
262 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); | 298 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); |
263 | Exception e = new InventoryArchiverException(errorMessage); | 299 | Exception e = new InventoryArchiverException(errorMessage); |
264 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); | 300 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); |
265 | throw e; | 301 | throw e; |
266 | } | 302 | } |
267 | 303 | ||
268 | m_archiveWriter = new TarArchiveWriter(m_saveStream); | 304 | m_archiveWriter = new TarArchiveWriter(m_saveStream); |
269 | 305 | ||
270 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); | 306 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); |
@@ -278,10 +314,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
278 | { | 314 | { |
279 | m_log.DebugFormat( | 315 | m_log.DebugFormat( |
280 | "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", | 316 | "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", |
281 | inventoryFolder.Name, | 317 | inventoryFolder.Name, |
282 | inventoryFolder.ID, | 318 | inventoryFolder.ID, |
283 | m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); | 319 | m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); |
284 | 320 | ||
285 | //recurse through all dirs getting dirs and files | 321 | //recurse through all dirs getting dirs and files |
286 | SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); | 322 | SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); |
287 | } | 323 | } |
@@ -290,10 +326,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
290 | m_log.DebugFormat( | 326 | m_log.DebugFormat( |
291 | "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", | 327 | "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", |
292 | inventoryItem.Name, inventoryItem.ID, m_invPath); | 328 | inventoryItem.Name, inventoryItem.ID, m_invPath); |
293 | 329 | ||
294 | SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); | 330 | SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); |
295 | } | 331 | } |
296 | 332 | ||
297 | // Don't put all this profile information into the archive right now. | 333 | // Don't put all this profile information into the archive right now. |
298 | //SaveUsers(); | 334 | //SaveUsers(); |
299 | 335 | ||
@@ -352,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
352 | /// | 388 | /// |
353 | /// These names are prepended with an inventory folder's UUID so that more than one folder can have the | 389 | /// These names are prepended with an inventory folder's UUID so that more than one folder can have the |
354 | /// same name | 390 | /// same name |
355 | /// | 391 | /// |
356 | /// <param name="folder"></param> | 392 | /// <param name="folder"></param> |
357 | /// <returns></returns> | 393 | /// <returns></returns> |
358 | public static string CreateArchiveFolderName(InventoryFolderBase folder) | 394 | public static string CreateArchiveFolderName(InventoryFolderBase folder) |
@@ -366,7 +402,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
366 | /// | 402 | /// |
367 | /// These names are prepended with an inventory item's UUID so that more than one item can have the | 403 | /// These names are prepended with an inventory item's UUID so that more than one item can have the |
368 | /// same name | 404 | /// same name |
369 | /// | 405 | /// |
370 | /// <param name="item"></param> | 406 | /// <param name="item"></param> |
371 | /// <returns></returns> | 407 | /// <returns></returns> |
372 | public static string CreateArchiveItemName(InventoryItemBase item) | 408 | public static string CreateArchiveItemName(InventoryItemBase item) |
@@ -412,7 +448,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
412 | public string CreateControlFile(Dictionary<string, object> options) | 448 | public string CreateControlFile(Dictionary<string, object> options) |
413 | { | 449 | { |
414 | int majorVersion, minorVersion; | 450 | int majorVersion, minorVersion; |
415 | 451 | ||
416 | if (options.ContainsKey("home")) | 452 | if (options.ContainsKey("home")) |
417 | { | 453 | { |
418 | majorVersion = 1; | 454 | majorVersion = 1; |
@@ -422,10 +458,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
422 | { | 458 | { |
423 | majorVersion = 0; | 459 | majorVersion = 0; |
424 | minorVersion = 3; | 460 | minorVersion = 3; |
425 | } | 461 | } |
426 | 462 | ||
427 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); | 463 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); |
428 | 464 | ||
429 | StringWriter sw = new StringWriter(); | 465 | StringWriter sw = new StringWriter(); |
430 | XmlTextWriter xtw = new XmlTextWriter(sw); | 466 | XmlTextWriter xtw = new XmlTextWriter(sw); |
431 | xtw.Formatting = Formatting.Indented; | 467 | xtw.Formatting = Formatting.Indented; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index ac22c3f..cf87010 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -47,18 +47,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
47 | public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule | 47 | public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule |
48 | { | 48 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 50 | ||
51 | public string Name { get { return "Inventory Archiver Module"; } } | 51 | public string Name { get { return "Inventory Archiver Module"; } } |
52 | 52 | ||
53 | public bool IsSharedModule { get { return true; } } | 53 | public bool IsSharedModule { get { return true; } } |
54 | 54 | ||
55 | /// <value> | 55 | /// <value> |
56 | /// Enable or disable checking whether the iar user is actually logged in | 56 | /// Enable or disable checking whether the iar user is actually logged in |
57 | /// </value> | 57 | /// </value> |
58 | // public bool DisablePresenceChecks { get; set; } | 58 | // public bool DisablePresenceChecks { get; set; } |
59 | 59 | ||
60 | public event InventoryArchiveSaved OnInventoryArchiveSaved; | 60 | public event InventoryArchiveSaved OnInventoryArchiveSaved; |
61 | 61 | ||
62 | /// <summary> | 62 | /// <summary> |
63 | /// The file to load and save inventory if no filename has been specified | 63 | /// The file to load and save inventory if no filename has been specified |
64 | /// </summary> | 64 | /// </summary> |
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
68 | /// Pending save completions initiated from the console | 68 | /// Pending save completions initiated from the console |
69 | /// </value> | 69 | /// </value> |
70 | protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); | 70 | protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); |
71 | 71 | ||
72 | /// <value> | 72 | /// <value> |
73 | /// All scenes that this module knows about | 73 | /// All scenes that this module knows about |
74 | /// </value> | 74 | /// </value> |
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
106 | { | 106 | { |
107 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); | 107 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); |
108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; | 108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; |
109 | 109 | ||
110 | scene.AddCommand( | 110 | scene.AddCommand( |
111 | "Archiving", this, "load iar", | 111 | "Archiving", this, "load iar", |
112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", | 112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", |
@@ -119,11 +119,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
119 | + "<IAR path> is the filesystem path or URI from which to load the IAR." | 119 | + "<IAR path> is the filesystem path or URI from which to load the IAR." |
120 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), | 120 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), |
121 | HandleLoadInvConsoleCommand); | 121 | HandleLoadInvConsoleCommand); |
122 | 122 | ||
123 | scene.AddCommand( | 123 | scene.AddCommand( |
124 | "Archiving", this, "save iar", | 124 | "Archiving", this, "save iar", |
125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", | 125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]", |
126 | "Save user inventory archive (IAR).", | 126 | "Save user inventory archive (IAR).", |
127 | "<first> is the user's first name.\n" | 127 | "<first> is the user's first name.\n" |
128 | + "<last> is the user's last name.\n" | 128 | + "<last> is the user's last name.\n" |
129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" | 129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" |
@@ -131,32 +131,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
131 | + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) | 131 | + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) |
132 | + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" | 132 | + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" |
133 | + "-c|--creators preserves information about foreign creators.\n" | 133 | + "-c|--creators preserves information about foreign creators.\n" |
134 | + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine | ||
135 | + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine | ||
134 | + "-v|--verbose extra debug messages.\n" | 136 | + "-v|--verbose extra debug messages.\n" |
135 | + "--noassets stops assets being saved to the IAR.", | 137 | + "--noassets stops assets being saved to the IAR.", |
136 | HandleSaveInvConsoleCommand); | 138 | HandleSaveInvConsoleCommand); |
137 | 139 | ||
138 | m_aScene = scene; | 140 | m_aScene = scene; |
139 | } | 141 | } |
140 | 142 | ||
141 | m_scenes[scene.RegionInfo.RegionID] = scene; | 143 | m_scenes[scene.RegionInfo.RegionID] = scene; |
142 | } | 144 | } |
143 | 145 | ||
144 | public void PostInitialise() {} | 146 | public void PostInitialise() {} |
145 | 147 | ||
146 | public void Close() {} | 148 | public void Close() {} |
147 | 149 | ||
148 | /// <summary> | 150 | /// <summary> |
149 | /// Trigger the inventory archive saved event. | 151 | /// Trigger the inventory archive saved event. |
150 | /// </summary> | 152 | /// </summary> |
151 | protected internal void TriggerInventoryArchiveSaved( | 153 | protected internal void TriggerInventoryArchiveSaved( |
152 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 154 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
153 | Exception reportedException) | 155 | Exception reportedException) |
154 | { | 156 | { |
155 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; | 157 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; |
156 | if (handlerInventoryArchiveSaved != null) | 158 | if (handlerInventoryArchiveSaved != null) |
157 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); | 159 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); |
158 | } | 160 | } |
159 | 161 | ||
160 | public bool ArchiveInventory( | 162 | public bool ArchiveInventory( |
161 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | 163 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) |
162 | { | 164 | { |
@@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
164 | } | 166 | } |
165 | 167 | ||
166 | public bool ArchiveInventory( | 168 | public bool ArchiveInventory( |
167 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | 169 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, |
168 | Dictionary<string, object> options) | 170 | Dictionary<string, object> options) |
169 | { | 171 | { |
170 | if (m_scenes.Count > 0) | 172 | if (m_scenes.Count > 0) |
@@ -188,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
188 | 190 | ||
189 | return false; | 191 | return false; |
190 | } | 192 | } |
191 | 193 | ||
192 | return true; | 194 | return true; |
193 | // } | 195 | // } |
194 | // else | 196 | // else |
@@ -202,15 +204,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
202 | 204 | ||
203 | return false; | 205 | return false; |
204 | } | 206 | } |
205 | 207 | ||
206 | public bool ArchiveInventory( | 208 | public bool ArchiveInventory( |
207 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | 209 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, |
208 | Dictionary<string, object> options) | 210 | Dictionary<string, object> options) |
209 | { | 211 | { |
210 | if (m_scenes.Count > 0) | 212 | if (m_scenes.Count > 0) |
211 | { | 213 | { |
212 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); | 214 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); |
213 | 215 | ||
214 | if (userInfo != null) | 216 | if (userInfo != null) |
215 | { | 217 | { |
216 | // if (CheckPresence(userInfo.PrincipalID)) | 218 | // if (CheckPresence(userInfo.PrincipalID)) |
@@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
228 | 230 | ||
229 | return false; | 231 | return false; |
230 | } | 232 | } |
231 | 233 | ||
232 | return true; | 234 | return true; |
233 | // } | 235 | // } |
234 | // else | 236 | // else |
@@ -239,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
239 | // } | 241 | // } |
240 | } | 242 | } |
241 | } | 243 | } |
242 | 244 | ||
243 | return false; | 245 | return false; |
244 | } | 246 | } |
245 | 247 | ||
@@ -247,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
247 | { | 249 | { |
248 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); | 250 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); |
249 | } | 251 | } |
250 | 252 | ||
251 | public bool DearchiveInventory( | 253 | public bool DearchiveInventory( |
252 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | 254 | string firstName, string lastName, string invPath, string pass, Stream loadStream, |
253 | Dictionary<string, object> options) | 255 | Dictionary<string, object> options) |
254 | { | 256 | { |
255 | if (m_scenes.Count > 0) | 257 | if (m_scenes.Count > 0) |
@@ -295,22 +297,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
295 | 297 | ||
296 | return false; | 298 | return false; |
297 | } | 299 | } |
298 | 300 | ||
299 | public bool DearchiveInventory( | 301 | public bool DearchiveInventory( |
300 | string firstName, string lastName, string invPath, string pass, string loadPath, | 302 | string firstName, string lastName, string invPath, string pass, string loadPath, |
301 | Dictionary<string, object> options) | 303 | Dictionary<string, object> options) |
302 | { | 304 | { |
303 | if (m_scenes.Count > 0) | 305 | if (m_scenes.Count > 0) |
304 | { | 306 | { |
305 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); | 307 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); |
306 | 308 | ||
307 | if (userInfo != null) | 309 | if (userInfo != null) |
308 | { | 310 | { |
309 | // if (CheckPresence(userInfo.PrincipalID)) | 311 | // if (CheckPresence(userInfo.PrincipalID)) |
310 | // { | 312 | // { |
311 | InventoryArchiveReadRequest request; | 313 | InventoryArchiveReadRequest request; |
312 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); | 314 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); |
313 | 315 | ||
314 | try | 316 | try |
315 | { | 317 | { |
316 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); | 318 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); |
@@ -324,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
324 | 326 | ||
325 | return false; | 327 | return false; |
326 | } | 328 | } |
327 | 329 | ||
328 | UpdateClientWithLoadedNodes(userInfo, request.Execute()); | 330 | UpdateClientWithLoadedNodes(userInfo, request.Execute()); |
329 | 331 | ||
330 | return true; | 332 | return true; |
@@ -340,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
340 | 342 | ||
341 | return false; | 343 | return false; |
342 | } | 344 | } |
343 | 345 | ||
344 | /// <summary> | 346 | /// <summary> |
345 | /// Load inventory from an inventory file archive | 347 | /// Load inventory from an inventory file archive |
346 | /// </summary> | 348 | /// </summary> |
@@ -351,26 +353,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
351 | { | 353 | { |
352 | Dictionary<string, object> options = new Dictionary<string, object>(); | 354 | Dictionary<string, object> options = new Dictionary<string, object>(); |
353 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); | 355 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); |
354 | 356 | ||
355 | List<string> mainParams = optionSet.Parse(cmdparams); | 357 | List<string> mainParams = optionSet.Parse(cmdparams); |
356 | 358 | ||
357 | if (mainParams.Count < 6) | 359 | if (mainParams.Count < 6) |
358 | { | 360 | { |
359 | m_log.Error( | 361 | m_log.Error( |
360 | "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); | 362 | "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); |
361 | return; | 363 | return; |
362 | } | 364 | } |
363 | 365 | ||
364 | string firstName = mainParams[2]; | 366 | string firstName = mainParams[2]; |
365 | string lastName = mainParams[3]; | 367 | string lastName = mainParams[3]; |
366 | string invPath = mainParams[4]; | 368 | string invPath = mainParams[4]; |
367 | string pass = mainParams[5]; | 369 | string pass = mainParams[5]; |
368 | string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); | 370 | string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); |
369 | 371 | ||
370 | m_log.InfoFormat( | 372 | m_log.InfoFormat( |
371 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", | 373 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", |
372 | loadPath, invPath, firstName, lastName); | 374 | loadPath, invPath, firstName, lastName); |
373 | 375 | ||
374 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) | 376 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) |
375 | m_log.InfoFormat( | 377 | m_log.InfoFormat( |
376 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", | 378 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", |
@@ -381,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
381 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 383 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
382 | } | 384 | } |
383 | } | 385 | } |
384 | 386 | ||
385 | /// <summary> | 387 | /// <summary> |
386 | /// Save inventory to a file archive | 388 | /// Save inventory to a file archive |
387 | /// </summary> | 389 | /// </summary> |
@@ -398,6 +400,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
398 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); | 400 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); |
399 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); | 401 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); |
400 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 402 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
403 | ops.Add("e|exclude=", delegate(string v) | ||
404 | { | ||
405 | if (!options.ContainsKey("exclude")) | ||
406 | options["exclude"] = new List<String>(); | ||
407 | ((List<String>)options["exclude"]).Add(v); | ||
408 | }); | ||
409 | ops.Add("f|excludefolder=", delegate(string v) | ||
410 | { | ||
411 | if (!options.ContainsKey("excludefolders")) | ||
412 | options["excludefolders"] = new List<String>(); | ||
413 | ((List<String>)options["excludefolders"]).Add(v); | ||
414 | }); | ||
401 | 415 | ||
402 | List<string> mainParams = ops.Parse(cmdparams); | 416 | List<string> mainParams = ops.Parse(cmdparams); |
403 | 417 | ||
@@ -406,10 +420,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | if (mainParams.Count < 6) | 420 | if (mainParams.Count < 6) |
407 | { | 421 | { |
408 | m_log.Error( | 422 | m_log.Error( |
409 | "[INVENTORY ARCHIVER]: usage is save iar [-h|--home=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>] [-c|--creators] [-v|--verbose]"); | 423 | "[INVENTORY ARCHIVER]: save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]"); |
410 | return; | 424 | return; |
411 | } | 425 | } |
412 | 426 | ||
413 | if (options.ContainsKey("home")) | 427 | if (options.ContainsKey("home")) |
414 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); | 428 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); |
415 | 429 | ||
@@ -418,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
418 | string invPath = mainParams[4]; | 432 | string invPath = mainParams[4]; |
419 | string pass = mainParams[5]; | 433 | string pass = mainParams[5]; |
420 | string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); | 434 | string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); |
421 | 435 | ||
422 | m_log.InfoFormat( | 436 | m_log.InfoFormat( |
423 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", | 437 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", |
424 | savePath, invPath, firstName, lastName); | 438 | savePath, invPath, firstName, lastName); |
@@ -433,9 +447,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
433 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 447 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
434 | } | 448 | } |
435 | } | 449 | } |
436 | 450 | ||
437 | private void SaveInvConsoleCommandCompleted( | 451 | private void SaveInvConsoleCommandCompleted( |
438 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 452 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
439 | Exception reportedException) | 453 | Exception reportedException) |
440 | { | 454 | { |
441 | lock (m_pendingConsoleSaves) | 455 | lock (m_pendingConsoleSaves) |
@@ -445,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
445 | else | 459 | else |
446 | return; | 460 | return; |
447 | } | 461 | } |
448 | 462 | ||
449 | if (succeeded) | 463 | if (succeeded) |
450 | { | 464 | { |
451 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); | 465 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); |
@@ -453,11 +467,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
453 | else | 467 | else |
454 | { | 468 | { |
455 | m_log.ErrorFormat( | 469 | m_log.ErrorFormat( |
456 | "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", | 470 | "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", |
457 | userInfo.FirstName, userInfo.LastName, reportedException.Message); | 471 | userInfo.FirstName, userInfo.LastName, reportedException.Message); |
458 | } | 472 | } |
459 | } | 473 | } |
460 | 474 | ||
461 | /// <summary> | 475 | /// <summary> |
462 | /// Get user information for the given name. | 476 | /// Get user information for the given name. |
463 | /// </summary> | 477 | /// </summary> |
@@ -467,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
467 | /// <returns></returns> | 481 | /// <returns></returns> |
468 | protected UserAccount GetUserInfo(string firstName, string lastName, string pass) | 482 | protected UserAccount GetUserInfo(string firstName, string lastName, string pass) |
469 | { | 483 | { |
470 | UserAccount account | 484 | UserAccount account |
471 | = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); | 485 | = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); |
472 | 486 | ||
473 | if (null == account) | 487 | if (null == account) |
474 | { | 488 | { |
475 | m_log.ErrorFormat( | 489 | m_log.ErrorFormat( |
476 | "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", | 490 | "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", |
477 | firstName, lastName); | 491 | firstName, lastName); |
478 | return null; | 492 | return null; |
479 | } | 493 | } |
@@ -488,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
488 | else | 502 | else |
489 | { | 503 | { |
490 | m_log.ErrorFormat( | 504 | m_log.ErrorFormat( |
491 | "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", | 505 | "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", |
492 | firstName, lastName); | 506 | firstName, lastName); |
493 | return null; | 507 | return null; |
494 | } | 508 | } |
@@ -499,7 +513,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
499 | return null; | 513 | return null; |
500 | } | 514 | } |
501 | } | 515 | } |
502 | 516 | ||
503 | /// <summary> | 517 | /// <summary> |
504 | /// Notify the client of loaded nodes if they are logged in | 518 | /// Notify the client of loaded nodes if they are logged in |
505 | /// </summary> | 519 | /// </summary> |
@@ -508,22 +522,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
508 | { | 522 | { |
509 | if (loadedNodes.Count == 0) | 523 | if (loadedNodes.Count == 0) |
510 | return; | 524 | return; |
511 | 525 | ||
512 | foreach (Scene scene in m_scenes.Values) | 526 | foreach (Scene scene in m_scenes.Values) |
513 | { | 527 | { |
514 | ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); | 528 | ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); |
515 | 529 | ||
516 | if (user != null && !user.IsChildAgent) | 530 | if (user != null && !user.IsChildAgent) |
517 | { | 531 | { |
518 | foreach (InventoryNodeBase node in loadedNodes) | 532 | foreach (InventoryNodeBase node in loadedNodes) |
519 | { | 533 | { |
520 | // m_log.DebugFormat( | 534 | // m_log.DebugFormat( |
521 | // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", | 535 | // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", |
522 | // user.Name, node.Name); | 536 | // user.Name, node.Name); |
523 | 537 | ||
524 | user.ControllingClient.SendBulkUpdateInventory(node); | 538 | user.ControllingClient.SendBulkUpdateInventory(node); |
525 | } | 539 | } |
526 | 540 | ||
527 | break; | 541 | break; |
528 | } | 542 | } |
529 | } | 543 | } |
@@ -538,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
538 | // { | 552 | // { |
539 | // if (DisablePresenceChecks) | 553 | // if (DisablePresenceChecks) |
540 | // return true; | 554 | // return true; |
541 | // | 555 | // |
542 | // foreach (Scene scene in m_scenes.Values) | 556 | // foreach (Scene scene in m_scenes.Values) |
543 | // { | 557 | // { |
544 | // ScenePresence p; | 558 | // ScenePresence p; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index 19ef571..1056865 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock; | |||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 49 | { |
50 | [TestFixture] | 50 | [TestFixture] |
51 | public class InventoryArchiveTestCase | 51 | public class InventoryArchiveTestCase : OpenSimTestCase |
52 | { | 52 | { |
53 | protected ManualResetEvent mre = new ManualResetEvent(false); | 53 | protected ManualResetEvent mre = new ManualResetEvent(false); |
54 | 54 | ||
@@ -84,8 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
84 | protected string m_coaItemName = "Coalesced Item"; | 84 | protected string m_coaItemName = "Coalesced Item"; |
85 | 85 | ||
86 | [SetUp] | 86 | [SetUp] |
87 | public virtual void SetUp() | 87 | public override void SetUp() |
88 | { | 88 | { |
89 | base.SetUp(); | ||
89 | m_iarStream = new MemoryStream(m_iarStreamBytes); | 90 | m_iarStream = new MemoryStream(m_iarStreamBytes); |
90 | } | 91 | } |
91 | 92 | ||
@@ -100,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
100 | // log4net.Config.XmlConfigurator.Configure(); | 101 | // log4net.Config.XmlConfigurator.Configure(); |
101 | 102 | ||
102 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 103 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
103 | Scene scene = SceneHelpers.SetupScene(); | 104 | Scene scene = new SceneHelpers().SetupScene(); |
104 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 105 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
105 | 106 | ||
106 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); | 107 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index e409c8e..b112b6d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
61 | SerialiserModule serialiserModule = new SerialiserModule(); | 61 | SerialiserModule serialiserModule = new SerialiserModule(); |
62 | m_archiverModule = new InventoryArchiverModule(); | 62 | m_archiverModule = new InventoryArchiverModule(); |
63 | 63 | ||
64 | m_scene = SceneHelpers.SetupScene(); | 64 | m_scene = new SceneHelpers().SetupScene(); |
65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | 65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); |
66 | } | 66 | } |
67 | 67 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 417c20c..6eb3605 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs | |||
@@ -62,7 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
62 | 62 | ||
63 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 63 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
64 | 64 | ||
65 | Scene scene = SceneHelpers.SetupScene(); | 65 | Scene scene = new SceneHelpers().SetupScene(); |
66 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 66 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
67 | 67 | ||
68 | // Create user | 68 | // Create user |
@@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
179 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 179 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
180 | 180 | ||
181 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene | 181 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene |
182 | Scene scene = SceneHelpers.SetupScene(); | 182 | Scene scene = new SceneHelpers().SetupScene(); |
183 | 183 | ||
184 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 184 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
185 | 185 | ||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
222 | 222 | ||
223 | SerialiserModule serialiserModule = new SerialiserModule(); | 223 | SerialiserModule serialiserModule = new SerialiserModule(); |
224 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 224 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
225 | Scene scene = SceneHelpers.SetupScene(); | 225 | Scene scene = new SceneHelpers().SetupScene(); |
226 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 226 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
227 | 227 | ||
228 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); | 228 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); |
@@ -247,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
247 | 247 | ||
248 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 248 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
249 | 249 | ||
250 | Scene scene = SceneHelpers.SetupScene(); | 250 | Scene scene = new SceneHelpers().SetupScene(); |
251 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 251 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
252 | 252 | ||
253 | // Create user | 253 | // Create user |
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
326 | TestHelpers.InMethod(); | 326 | TestHelpers.InMethod(); |
327 | // log4net.Config.XmlConfigurator.Configure(); | 327 | // log4net.Config.XmlConfigurator.Configure(); |
328 | 328 | ||
329 | Scene scene = SceneHelpers.SetupScene(); | 329 | Scene scene = new SceneHelpers().SetupScene(); |
330 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 330 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
331 | 331 | ||
332 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 332 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); |
@@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
393 | TestHelpers.InMethod(); | 393 | TestHelpers.InMethod(); |
394 | //log4net.Config.XmlConfigurator.Configure(); | 394 | //log4net.Config.XmlConfigurator.Configure(); |
395 | 395 | ||
396 | Scene scene = SceneHelpers.SetupScene(); | 396 | Scene scene = new SceneHelpers().SetupScene(); |
397 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 397 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
398 | 398 | ||
399 | string folder1ExistingName = "a"; | 399 | string folder1ExistingName = "a"; |
@@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
444 | TestHelpers.InMethod(); | 444 | TestHelpers.InMethod(); |
445 | // log4net.Config.XmlConfigurator.Configure(); | 445 | // log4net.Config.XmlConfigurator.Configure(); |
446 | 446 | ||
447 | Scene scene = SceneHelpers.SetupScene(); | 447 | Scene scene = new SceneHelpers().SetupScene(); |
448 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 448 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
449 | 449 | ||
450 | string folder1ExistingName = "a"; | 450 | string folder1ExistingName = "a"; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index bc5c1ff..92cf9d1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -240,13 +240,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
240 | { | 240 | { |
241 | ScenePresence sp = scene.GetScenePresence(client.AgentId); | 241 | ScenePresence sp = scene.GetScenePresence(client.AgentId); |
242 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); | 242 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); |
243 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | 243 | |
244 | if (transferMod != null && sp != null && eq != null) | 244 | if (transferMod != null && sp != null) |
245 | transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); | 245 | transferMod.DoTeleport( |
246 | sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), | ||
247 | Vector3.UnitX, teleportflags); | ||
246 | } | 248 | } |
247 | } | 249 | } |
248 | } | 250 | } |
249 | } | 251 | } |
250 | } | 252 | } |
251 | } | 253 | } |
252 | } | 254 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index dcfdf8f..a889984 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -151,6 +151,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
151 | Scene scene = (Scene)(client.Scene); | 151 | Scene scene = (Scene)(client.Scene); |
152 | ScenePresence presence = scene.GetScenePresence(client.AgentId); | 152 | ScenePresence presence = scene.GetScenePresence(client.AgentId); |
153 | 153 | ||
154 | // Round up Z co-ordinate rather than round-down by casting. This stops tall avatars from being given | ||
155 | // a teleport Z co-ordinate by short avatars that drops them through or embeds them in thin floors on | ||
156 | // arrival. | ||
157 | // | ||
158 | // Ideally we would give the exact float position adjusting for the relative height of the two avatars | ||
159 | // but it looks like a float component isn't possible with a parcel ID. | ||
154 | UUID dest = Util.BuildFakeParcelID( | 160 | UUID dest = Util.BuildFakeParcelID( |
155 | scene.RegionInfo.RegionHandle, | 161 | scene.RegionInfo.RegionHandle, |
156 | (uint)presence.AbsolutePosition.X, | 162 | (uint)presence.AbsolutePosition.X, |
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index 8101ca2..87ca327 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | |||
@@ -57,14 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile | |||
57 | 57 | ||
58 | public void Initialise(IConfigSource config) | 58 | public void Initialise(IConfigSource config) |
59 | { | 59 | { |
60 | // This can be reduced later as the loader will determine | ||
61 | // whether we are needed | ||
62 | if (config.Configs["Profile"] != null) | ||
63 | { | ||
64 | if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule") | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); | 60 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); |
69 | m_Enabled = true; | 61 | m_Enabled = true; |
70 | } | 62 | } |