diff options
Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
Conflicts:
bin/Regions/Regions.ini.example
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
19 files changed, 1215 insertions, 689 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 7cc5092..cb724aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
49 | { | 49 | { |
50 | #region INonSharedRegionModule | 50 | #region INonSharedRegionModule |
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 | |||
53 | public int DebugLevel { get; set; } | ||
52 | 54 | ||
53 | private Scene m_scene; | 55 | private Scene m_scene; |
54 | private IInventoryAccessModule m_invAccessModule; | 56 | private IInventoryAccessModule m_invAccessModule; |
@@ -76,10 +78,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
76 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | 78 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); |
77 | 79 | ||
78 | if (Enabled) | 80 | if (Enabled) |
81 | { | ||
79 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 82 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
83 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | ||
84 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | ||
85 | |||
86 | MainConsole.Instance.Commands.AddCommand( | ||
87 | "Debug", | ||
88 | false, | ||
89 | "debug attachments", | ||
90 | "debug attachments [0|1]", | ||
91 | "Turn on attachments debugging\n" | ||
92 | + " <= 0 - turns off debugging\n" | ||
93 | + " >= 1 - turns on attachment message logging\n", | ||
94 | HandleDebugAttachments); | ||
95 | } | ||
80 | 96 | ||
81 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI | 97 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI |
82 | } | 98 | } |
99 | |||
100 | private void HandleDebugAttachments(string module, string[] args) | ||
101 | { | ||
102 | int debugLevel; | ||
103 | |||
104 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | ||
105 | { | ||
106 | MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | DebugLevel = debugLevel; | ||
111 | MainConsole.Instance.OutputFormat( | ||
112 | "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /// <summary> | ||
117 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. | ||
118 | /// </summary> | ||
119 | /// <param name='localID'></param> | ||
120 | /// <param name='itemID'></param> | ||
121 | private void HandleScriptStateChange(uint localID, bool started) | ||
122 | { | ||
123 | SceneObjectGroup sog = m_scene.GetGroupByPrim(localID); | ||
124 | if (sog != null && sog.IsAttachment) | ||
125 | { | ||
126 | if (!started) | ||
127 | { | ||
128 | // FIXME: This is a convoluted way for working out whether the script state has changed to stop | ||
129 | // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below | ||
130 | // This needs to be handled in a less tangled way. | ||
131 | ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar); | ||
132 | if (sp.ControllingClient.IsActive) | ||
133 | sog.HasGroupChanged = true; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | sog.HasGroupChanged = true; | ||
138 | } | ||
139 | } | ||
140 | } | ||
83 | 141 | ||
84 | public void RemoveRegion(Scene scene) | 142 | public void RemoveRegion(Scene scene) |
85 | { | 143 | { |
@@ -153,10 +211,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
153 | } | 211 | } |
154 | } | 212 | } |
155 | 213 | ||
156 | /// <summary> | ||
157 | /// RezAttachments. This should only be called upon login on the first region. | ||
158 | /// Attachment rezzings on crossings and TPs are done in a different way. | ||
159 | /// </summary> | ||
160 | public void RezAttachments(IScenePresence sp) | 214 | public void RezAttachments(IScenePresence sp) |
161 | { | 215 | { |
162 | if (!Enabled) | 216 | if (!Enabled) |
@@ -165,10 +219,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
165 | if (null == sp.Appearance) | 219 | if (null == sp.Appearance) |
166 | { | 220 | { |
167 | m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); | 221 | m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); |
222 | |||
168 | return; | 223 | return; |
169 | } | 224 | } |
170 | 225 | ||
171 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); | 226 | if (sp.GetAttachments().Count > 0) |
227 | { | ||
228 | if (DebugLevel > 0) | ||
229 | m_log.DebugFormat( | ||
230 | "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments", | ||
231 | m_scene.Name, sp.Name); | ||
232 | |||
233 | return; | ||
234 | } | ||
235 | |||
236 | if (DebugLevel > 0) | ||
237 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); | ||
172 | 238 | ||
173 | XmlDocument doc = new XmlDocument(); | 239 | XmlDocument doc = new XmlDocument(); |
174 | string stateData = String.Empty; | 240 | string stateData = String.Empty; |
@@ -235,10 +301,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
235 | 301 | ||
236 | // If we're an NPC then skip all the item checks and manipulations since we don't have an | 302 | // If we're an NPC then skip all the item checks and manipulations since we don't have an |
237 | // inventory right now. | 303 | // inventory right now. |
238 | if (sp.PresenceType == PresenceType.Npc) | 304 | RezSingleAttachmentFromInventoryInternal( |
239 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true); | 305 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null); |
240 | else | ||
241 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d); | ||
242 | } | 306 | } |
243 | catch (Exception e) | 307 | catch (Exception e) |
244 | { | 308 | { |
@@ -254,14 +318,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
254 | if (!Enabled) | 318 | if (!Enabled) |
255 | return; | 319 | return; |
256 | 320 | ||
257 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | 321 | if (DebugLevel > 0) |
322 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
323 | |||
324 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
325 | |||
326 | if (attachments.Count <= 0) | ||
327 | return; | ||
328 | |||
329 | Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>(); | ||
330 | |||
331 | foreach (SceneObjectGroup so in attachments) | ||
332 | { | ||
333 | // Scripts MUST be snapshotted before the object is | ||
334 | // removed from the scene because doing otherwise will | ||
335 | // clobber the run flag | ||
336 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
337 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
338 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | ||
339 | } | ||
258 | 340 | ||
259 | lock (sp.AttachmentsSyncLock) | 341 | lock (sp.AttachmentsSyncLock) |
260 | { | 342 | { |
261 | foreach (SceneObjectGroup so in sp.GetAttachments()) | 343 | foreach (SceneObjectGroup so in attachments) |
262 | { | 344 | UpdateDetachedObject(sp, so, scriptStates[so]); |
263 | UpdateDetachedObject(sp, so); | ||
264 | } | ||
265 | 345 | ||
266 | sp.ClearAttachments(); | 346 | sp.ClearAttachments(); |
267 | } | 347 | } |
@@ -272,9 +352,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
272 | if (!Enabled) | 352 | if (!Enabled) |
273 | return; | 353 | return; |
274 | 354 | ||
275 | // m_log.DebugFormat( | 355 | if (DebugLevel > 0) |
276 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | 356 | m_log.DebugFormat( |
277 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | 357 | "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", |
358 | m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
278 | 359 | ||
279 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 360 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
280 | { | 361 | { |
@@ -284,110 +365,95 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
284 | sp.ClearAttachments(); | 365 | sp.ClearAttachments(); |
285 | } | 366 | } |
286 | 367 | ||
287 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append) | 368 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append) |
288 | { | 369 | { |
289 | if (!Enabled) | 370 | if (!Enabled) |
290 | return false; | 371 | return false; |
291 | 372 | ||
292 | if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, append)) | 373 | return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append); |
293 | { | ||
294 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | ||
295 | return true; | ||
296 | } | ||
297 | |||
298 | return false; | ||
299 | } | 374 | } |
300 | 375 | ||
301 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append) | 376 | /// <summary> |
377 | /// Internal method which actually does all the work for attaching an object. | ||
378 | /// </summary> | ||
379 | /// <returns>The object attached.</returns> | ||
380 | /// <param name='sp'></param> | ||
381 | /// <param name='group'>The object to attach.</param> | ||
382 | /// <param name='attachmentPt'></param> | ||
383 | /// <param name='silent'></param> | ||
384 | /// <param name='addToInventory'>If true then add object to user inventory.</param> | ||
385 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> | ||
386 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append) | ||
302 | { | 387 | { |
303 | lock (sp.AttachmentsSyncLock) | ||
304 | { | ||
305 | // m_log.DebugFormat( | 388 | // m_log.DebugFormat( |
306 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | 389 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
307 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | 390 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); |
308 | 391 | ||
309 | if (group.GetSittingAvatarsCount() != 0) | 392 | if (sp.GetAttachments().Contains(group)) |
310 | { | 393 | { |
311 | // m_log.WarnFormat( | 394 | // m_log.WarnFormat( |
312 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | 395 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", |
313 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | 396 | // group.Name, group.LocalId, sp.Name, AttachmentPt); |
314 | |||
315 | return false; | ||
316 | } | ||
317 | |||
318 | if (sp.GetAttachments(attachmentPt).Contains(group)) | ||
319 | { | ||
320 | // m_log.WarnFormat( | ||
321 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
322 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | ||
323 | |||
324 | return false; | ||
325 | } | ||
326 | |||
327 | Vector3 attachPos = group.AbsolutePosition; | ||
328 | |||
329 | // If the attachment point isn't the same as the one previously used | ||
330 | // set it's offset position = 0 so that it appears on the attachment point | ||
331 | // and not in a weird location somewhere unknown. | ||
332 | if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint) | ||
333 | { | ||
334 | attachPos = Vector3.Zero; | ||
335 | } | ||
336 | |||
337 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
338 | if (attachmentPt == 0) | ||
339 | { | ||
340 | // Check object for stored attachment point | ||
341 | attachmentPt = group.AttachmentPoint; | ||
342 | } | ||
343 | |||
344 | // if we still didn't find a suitable attachment point....... | ||
345 | if (attachmentPt == 0) | ||
346 | { | ||
347 | // Stick it on left hand with Zero Offset from the attachment point. | ||
348 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
349 | attachPos = Vector3.Zero; | ||
350 | } | ||
351 | |||
352 | if (useAttachData) | ||
353 | { | ||
354 | group.RootPart.RotationOffset = group.RootPart.AttachRotation; | ||
355 | attachPos = group.RootPart.AttachOffset; | ||
356 | if (attachmentPt == 0) | ||
357 | { | ||
358 | attachmentPt = group.RootPart.AttachPoint; | ||
359 | if (attachmentPt == 0) | ||
360 | { | ||
361 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
362 | attachPos = Vector3.Zero; | ||
363 | } | ||
364 | } | ||
365 | else if (group.RootPart.AttachPoint != attachmentPt) | ||
366 | { | ||
367 | attachPos = Vector3.Zero; | ||
368 | } | ||
369 | } | ||
370 | group.AttachmentPoint = attachmentPt; | ||
371 | group.AbsolutePosition = attachPos; | ||
372 | 397 | ||
373 | if (sp.PresenceType != PresenceType.Npc) | 398 | return false; |
374 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); | ||
375 | |||
376 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | ||
377 | } | 399 | } |
378 | 400 | ||
379 | return true; | 401 | if (group.GetSittingAvatarsCount() != 0) |
380 | } | 402 | { |
403 | if (DebugLevel > 0) | ||
404 | m_log.WarnFormat( | ||
405 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | ||
406 | group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | ||
407 | |||
408 | return false; | ||
409 | } | ||
410 | |||
411 | Vector3 attachPos = group.AbsolutePosition; | ||
412 | |||
413 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | ||
414 | // be removed when that functionality is implemented in opensim | ||
415 | attachmentPt &= 0x7f; | ||
416 | |||
417 | // If the attachment point isn't the same as the one previously used | ||
418 | // set it's offset position = 0 so that it appears on the attachment point | ||
419 | // and not in a weird location somewhere unknown. | ||
420 | if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint) | ||
421 | { | ||
422 | attachPos = Vector3.Zero; | ||
423 | } | ||
424 | |||
425 | // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. | ||
426 | if (attachmentPt == (uint)AttachmentPoint.Default) | ||
427 | { | ||
428 | // Check object for stored attachment point | ||
429 | attachmentPt = group.AttachmentPoint; | ||
430 | } | ||
431 | |||
432 | // if we still didn't find a suitable attachment point....... | ||
433 | if (attachmentPt == 0) | ||
434 | { | ||
435 | // Stick it on left hand with Zero Offset from the attachment point. | ||
436 | attachmentPt = (uint)AttachmentPoint.LeftHand; | ||
437 | attachPos = Vector3.Zero; | ||
438 | } | ||
381 | 439 | ||
382 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) | ||
383 | { | ||
384 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 440 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); |
385 | 441 | ||
442 | if (attachments.Contains(group)) | ||
443 | { | ||
444 | if (DebugLevel > 0) | ||
445 | m_log.WarnFormat( | ||
446 | "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | ||
447 | group.Name, group.LocalId, sp.Name, attachmentPt); | ||
448 | |||
449 | return false; | ||
450 | } | ||
451 | |||
386 | // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones | 452 | // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones |
387 | while (attachments.Count >= 5) | 453 | while (attachments.Count >= 5) |
388 | { | 454 | { |
389 | if (attachments[0].FromItemID != UUID.Zero) | 455 | if (attachments[0].FromItemID != UUID.Zero) |
390 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | 456 | DetachSingleAttachmentToInv(sp, attachments[0]); |
391 | attachments.RemoveAt(0); | 457 | attachments.RemoveAt(0); |
392 | } | 458 | } |
393 | 459 | ||
@@ -397,19 +463,43 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
397 | foreach (SceneObjectGroup g in attachments) | 463 | foreach (SceneObjectGroup g in attachments) |
398 | { | 464 | { |
399 | if (g.FromItemID != UUID.Zero) | 465 | if (g.FromItemID != UUID.Zero) |
400 | DetachSingleAttachmentToInvInternal(sp, g); | 466 | DetachSingleAttachmentToInv(sp, g); |
401 | } | 467 | } |
402 | } | 468 | } |
403 | 469 | ||
404 | // Add the new attachment to inventory if we don't already have it. | 470 | lock (sp.AttachmentsSyncLock) |
405 | if (!temp) | ||
406 | { | 471 | { |
407 | UUID newAttachmentItemID = group.FromItemID; | 472 | group.AttachmentPoint = attachmentPt; |
408 | if (newAttachmentItemID == UUID.Zero) | 473 | group.AbsolutePosition = attachPos; |
409 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
410 | 474 | ||
411 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); | 475 | if (addToInventory && sp.PresenceType != PresenceType.Npc) |
476 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); | ||
477 | |||
478 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | ||
479 | |||
480 | if (resumeScripts) | ||
481 | { | ||
482 | // Fire after attach, so we don't get messy perms dialogs | ||
483 | // 4 == AttachedRez | ||
484 | group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
485 | group.ResumeScripts(); | ||
486 | } | ||
487 | |||
488 | // Do this last so that event listeners have access to all the effects of the attachment | ||
489 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | ||
412 | } | 490 | } |
491 | |||
492 | return true; | ||
493 | } | ||
494 | |||
495 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool append) | ||
496 | { | ||
497 | // Add the new attachment to inventory if we don't already have it. | ||
498 | UUID newAttachmentItemID = group.FromItemID; | ||
499 | if (newAttachmentItemID == UUID.Zero) | ||
500 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
501 | |||
502 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); | ||
413 | } | 503 | } |
414 | 504 | ||
415 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 505 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
@@ -422,40 +512,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
422 | if (!Enabled) | 512 | if (!Enabled) |
423 | return null; | 513 | return null; |
424 | 514 | ||
425 | // m_log.DebugFormat( | 515 | if (DebugLevel > 0) |
426 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", | 516 | m_log.DebugFormat( |
427 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name); | 517 | "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", |
428 | 518 | (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); | |
429 | bool append = (AttachmentPt & 0x80) != 0; | ||
430 | AttachmentPt &= 0x7f; | ||
431 | 519 | ||
432 | // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). | 520 | // We check the attachments in the avatar appearance here rather than the objects attached to the |
433 | // This often happens during login - not sure the exact reason. | 521 | // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are |
434 | // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the | 522 | // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done |
435 | // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login | 523 | // because pre-outfit folder viewers (most version 1 viewers) require it. |
436 | // before anything has actually been attached. | ||
437 | bool alreadyOn = false; | 524 | bool alreadyOn = false; |
438 | List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); | 525 | List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments(); |
439 | foreach (SceneObjectGroup so in existingAttachments) | 526 | foreach (AvatarAttachment existingAttachment in existingAttachments) |
440 | { | 527 | { |
441 | if (so.FromItemID == itemID) | 528 | if (existingAttachment.ItemID == itemID) |
442 | { | 529 | { |
443 | alreadyOn = true; | 530 | alreadyOn = true; |
444 | break; | 531 | break; |
445 | } | 532 | } |
446 | } | 533 | } |
447 | 534 | ||
448 | // if (sp.Appearance.GetAttachmentForItem(itemID) != null) | ||
449 | if (alreadyOn) | 535 | if (alreadyOn) |
450 | { | 536 | { |
451 | // m_log.WarnFormat( | 537 | if (DebugLevel > 0) |
452 | // "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", | 538 | m_log.DebugFormat( |
453 | // sp.Name, itemID, AttachmentPt); | 539 | "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn", |
540 | sp.Name, itemID, AttachmentPt); | ||
454 | 541 | ||
455 | return null; | 542 | return null; |
456 | } | 543 | } |
457 | 544 | ||
458 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append); | 545 | bool append = (AttachmentPt & 0x80) != 0; |
546 | AttachmentPt &= 0x7f; | ||
547 | |||
548 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc); | ||
459 | } | 549 | } |
460 | 550 | ||
461 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 551 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -463,13 +553,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
463 | if (!Enabled) | 553 | if (!Enabled) |
464 | return; | 554 | return; |
465 | 555 | ||
466 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | 556 | if (DebugLevel > 0) |
467 | lock (sp.AttachmentsSyncLock) | 557 | m_log.DebugFormat( |
558 | "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}", | ||
559 | rezlist.Count, sp.Name, m_scene.Name); | ||
560 | |||
561 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | ||
468 | { | 562 | { |
469 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | 563 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); |
470 | { | ||
471 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); | ||
472 | } | ||
473 | } | 564 | } |
474 | } | 565 | } |
475 | 566 | ||
@@ -483,9 +574,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
483 | if (!Enabled) | 574 | if (!Enabled) |
484 | return; | 575 | return; |
485 | 576 | ||
486 | // m_log.DebugFormat( | 577 | if (DebugLevel > 0) |
487 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 578 | m_log.DebugFormat( |
488 | // sp.UUID, soLocalId); | 579 | "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
580 | sp.UUID, soLocalId); | ||
489 | 581 | ||
490 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 582 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
491 | 583 | ||
@@ -501,9 +593,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
501 | if (inventoryID == UUID.Zero) | 593 | if (inventoryID == UUID.Zero) |
502 | return; | 594 | return; |
503 | 595 | ||
504 | // m_log.DebugFormat( | 596 | if (DebugLevel > 0) |
505 | // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", | 597 | m_log.DebugFormat( |
506 | // so.Name, so.LocalId, inventoryID); | 598 | "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", |
599 | so.Name, so.LocalId, inventoryID); | ||
507 | 600 | ||
508 | lock (sp.AttachmentsSyncLock) | 601 | lock (sp.AttachmentsSyncLock) |
509 | { | 602 | { |
@@ -549,25 +642,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
549 | 642 | ||
550 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) | 643 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
551 | { | 644 | { |
645 | if (so.AttachedAvatar != sp.UUID) | ||
646 | { | ||
647 | m_log.WarnFormat( | ||
648 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
649 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
650 | |||
651 | return; | ||
652 | } | ||
653 | |||
654 | if (DebugLevel > 0) | ||
655 | m_log.DebugFormat( | ||
656 | "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}", | ||
657 | so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name); | ||
658 | |||
659 | // Scripts MUST be snapshotted before the object is | ||
660 | // removed from the scene because doing otherwise will | ||
661 | // clobber the run flag | ||
662 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
663 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
664 | string scriptedState = PrepareScriptInstanceForSave(so, true); | ||
665 | |||
552 | lock (sp.AttachmentsSyncLock) | 666 | lock (sp.AttachmentsSyncLock) |
553 | { | 667 | { |
554 | // Save avatar attachment information | 668 | // Save avatar attachment information |
555 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 669 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
556 | 670 | ||
557 | if (so.AttachedAvatar != sp.UUID) | ||
558 | { | ||
559 | m_log.WarnFormat( | ||
560 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
561 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
562 | |||
563 | return; | ||
564 | } | ||
565 | |||
566 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); | 671 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); |
567 | if (changed && m_scene.AvatarFactory != null) | 672 | if (changed && m_scene.AvatarFactory != null) |
568 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 673 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
569 | 674 | ||
570 | DetachSingleAttachmentToInvInternal(sp, so); | 675 | sp.RemoveAttachment(so); |
676 | UpdateDetachedObject(sp, so, scriptedState); | ||
571 | } | 677 | } |
572 | } | 678 | } |
573 | 679 | ||
@@ -674,12 +780,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
674 | 780 | ||
675 | grp.HasGroupChanged = false; // Prevent it being saved over and over | 781 | grp.HasGroupChanged = false; // Prevent it being saved over and over |
676 | } | 782 | } |
677 | // else | 783 | else if (DebugLevel > 0) |
678 | // { | 784 | { |
679 | // m_log.DebugFormat( | 785 | m_log.DebugFormat( |
680 | // "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | 786 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", |
681 | // grp.UUID, grp.AttachmentPoint); | 787 | grp.UUID, grp.AttachmentPoint); |
682 | // } | 788 | } |
683 | } | 789 | } |
684 | 790 | ||
685 | /// <summary> | 791 | /// <summary> |
@@ -697,9 +803,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
697 | private void AttachToAgent( | 803 | private void AttachToAgent( |
698 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 804 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
699 | { | 805 | { |
700 | // m_log.DebugFormat( | 806 | if (DebugLevel > 0) |
701 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 807 | m_log.DebugFormat( |
702 | // so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 808 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", |
809 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | ||
703 | 810 | ||
704 | so.DetachFromBackup(); | 811 | so.DetachFromBackup(); |
705 | 812 | ||
@@ -722,19 +829,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
722 | 829 | ||
723 | if (!silent) | 830 | if (!silent) |
724 | { | 831 | { |
725 | // Killing it here will cause the client to deselect it | 832 | if (so.HasPrivateAttachmentPoint) |
726 | // It then reappears on the avatar, deselected | ||
727 | // through the full update below | ||
728 | // | ||
729 | if (so.IsSelected) | ||
730 | { | ||
731 | m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); | ||
732 | } | ||
733 | else if (so.HasPrivateAttachmentPoint) | ||
734 | { | 833 | { |
735 | // m_log.DebugFormat( | 834 | if (DebugLevel > 0) |
736 | // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", | 835 | m_log.DebugFormat( |
737 | // so.Name, sp.Name, so.AttachmentPoint); | 836 | "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", |
837 | so.Name, sp.Name, so.AttachmentPoint); | ||
738 | 838 | ||
739 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the | 839 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the |
740 | // scene that it's no longer in their awareness. | 840 | // scene that it's no longer in their awareness. |
@@ -745,7 +845,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
745 | }); | 845 | }); |
746 | } | 846 | } |
747 | 847 | ||
748 | so.IsSelected = false; // fudge.... | 848 | // Fudge below is an extremely unhelpful comment. It's probably here so that the scheduled full update |
849 | // will succeed, as that will not update if an attachment is selected. | ||
850 | so.IsSelected = false; // fudge.... | ||
851 | |||
749 | so.ScheduleGroupForFullUpdate(); | 852 | so.ScheduleGroupForFullUpdate(); |
750 | } | 853 | } |
751 | 854 | ||
@@ -765,9 +868,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
765 | if (m_invAccessModule == null) | 868 | if (m_invAccessModule == null) |
766 | return null; | 869 | return null; |
767 | 870 | ||
768 | // m_log.DebugFormat( | 871 | if (DebugLevel > 0) |
769 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | 872 | m_log.DebugFormat( |
770 | // grp.Name, grp.LocalId, remoteClient.Name); | 873 | "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", |
874 | grp.Name, grp.LocalId, sp.Name); | ||
771 | 875 | ||
772 | InventoryItemBase newItem | 876 | InventoryItemBase newItem |
773 | = m_invAccessModule.CopyToInventory( | 877 | = m_invAccessModule.CopyToInventory( |
@@ -782,8 +886,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
782 | return newItem; | 886 | return newItem; |
783 | } | 887 | } |
784 | 888 | ||
785 | private string GetObjectScriptStates(SceneObjectGroup grp) | 889 | /// <summary> |
890 | /// Prepares the script instance for save. | ||
891 | /// </summary> | ||
892 | /// <remarks> | ||
893 | /// This involves triggering the detach event and getting the script state (which also stops the script) | ||
894 | /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a | ||
895 | /// running script is performing attachment operations. | ||
896 | /// </remarks> | ||
897 | /// <returns> | ||
898 | /// The script state ready for persistence. | ||
899 | /// </returns> | ||
900 | /// <param name='grp'> | ||
901 | /// </param> | ||
902 | /// <param name='fireDetachEvent'> | ||
903 | /// If true, then fire the script event before we save its state. | ||
904 | /// </param> | ||
905 | private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent) | ||
786 | { | 906 | { |
907 | if (fireDetachEvent) | ||
908 | m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero); | ||
909 | |||
787 | using (StringWriter sw = new StringWriter()) | 910 | using (StringWriter sw = new StringWriter()) |
788 | { | 911 | { |
789 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | 912 | using (XmlTextWriter writer = new XmlTextWriter(sw)) |
@@ -795,7 +918,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
795 | } | 918 | } |
796 | } | 919 | } |
797 | 920 | ||
798 | private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so) | 921 | private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState) |
799 | { | 922 | { |
800 | // Don't save attachments for HG visitors, it | 923 | // Don't save attachments for HG visitors, it |
801 | // messes up their inventory. When a HG visitor logs | 924 | // messes up their inventory. When a HG visitor logs |
@@ -808,11 +931,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
808 | && (m_scene.UserManagementModule == null | 931 | && (m_scene.UserManagementModule == null |
809 | || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); | 932 | || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); |
810 | 933 | ||
811 | // Scripts MUST be snapshotted before the object is | ||
812 | // removed from the scene because doing otherwise will | ||
813 | // clobber the run flag | ||
814 | string scriptedState = GetObjectScriptStates(so); | ||
815 | |||
816 | // Remove the object from the scene so no more updates | 934 | // Remove the object from the scene so no more updates |
817 | // are sent. Doing this before the below changes will ensure | 935 | // are sent. Doing this before the below changes will ensure |
818 | // updates can't cause "HUD artefacts" | 936 | // updates can't cause "HUD artefacts" |
@@ -836,97 +954,75 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
836 | so.RemoveScriptInstances(true); | 954 | so.RemoveScriptInstances(true); |
837 | } | 955 | } |
838 | 956 | ||
839 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) | ||
840 | { | ||
841 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | ||
842 | |||
843 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); | ||
844 | sp.RemoveAttachment(so); | ||
845 | |||
846 | UpdateDetachedObject(sp, so); | ||
847 | } | ||
848 | |||
849 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 957 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
850 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append) | 958 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc) |
851 | { | 959 | { |
852 | if (m_invAccessModule == null) | 960 | if (m_invAccessModule == null) |
853 | return null; | 961 | return null; |
854 | 962 | ||
855 | lock (sp.AttachmentsSyncLock) | 963 | SceneObjectGroup objatt; |
964 | |||
965 | if (itemID != UUID.Zero) | ||
966 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
967 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
968 | false, false, sp.UUID, true); | ||
969 | else | ||
970 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
971 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
972 | false, false, sp.UUID, true); | ||
973 | |||
974 | if (objatt == null) | ||
856 | { | 975 | { |
857 | SceneObjectGroup objatt; | 976 | m_log.WarnFormat( |
977 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
978 | itemID, sp.Name, attachmentPt); | ||
858 | 979 | ||
859 | if (itemID != UUID.Zero) | 980 | return null; |
860 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | 981 | } |
861 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
862 | false, false, sp.UUID, true); | ||
863 | else | ||
864 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
865 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
866 | false, false, sp.UUID, true); | ||
867 | 982 | ||
868 | if (objatt != null) | 983 | if (DebugLevel > 0) |
984 | m_log.DebugFormat( | ||
985 | "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | ||
986 | objatt.Name, sp.Name, attachmentPt, m_scene.Name); | ||
987 | |||
988 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | ||
989 | objatt.HasGroupChanged = false; | ||
990 | bool tainted = false; | ||
991 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
992 | tainted = true; | ||
993 | |||
994 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | ||
995 | // course of events. If not, then it's probably not worth trying to recover the situation | ||
996 | // since this is more likely to trigger further exceptions and confuse later debugging. If | ||
997 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent | ||
998 | // since other normal error conditions will simply return false instead. | ||
999 | // This will throw if the attachment fails | ||
1000 | try | ||
1001 | { | ||
1002 | if (doc != null) | ||
869 | { | 1003 | { |
870 | // m_log.DebugFormat( | 1004 | objatt.LoadScriptState(doc); |
871 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | 1005 | objatt.ResetOwnerChangeFlag(); |
872 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); | 1006 | } |
873 | |||
874 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | ||
875 | objatt.HasGroupChanged = false; | ||
876 | bool tainted = false; | ||
877 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
878 | tainted = true; | ||
879 | |||
880 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | ||
881 | // course of events. If not, then it's probably not worth trying to recover the situation | ||
882 | // since this is more likely to trigger further exceptions and confuse later debugging. If | ||
883 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent | ||
884 | // since other normal error conditions will simply return false instead. | ||
885 | // This will throw if the attachment fails | ||
886 | try | ||
887 | { | ||
888 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, false, append); | ||
889 | } | ||
890 | catch (Exception e) | ||
891 | { | ||
892 | m_log.ErrorFormat( | ||
893 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
894 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
895 | |||
896 | // Make sure the object doesn't stick around and bail | ||
897 | sp.RemoveAttachment(objatt); | ||
898 | m_scene.DeleteSceneObject(objatt, false); | ||
899 | return null; | ||
900 | } | ||
901 | |||
902 | if (tainted) | ||
903 | objatt.HasGroupChanged = true; | ||
904 | 1007 | ||
905 | if (doc != null) | 1008 | AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append); |
906 | { | 1009 | } |
907 | objatt.LoadScriptState(doc); | 1010 | catch (Exception e) |
908 | objatt.ResetOwnerChangeFlag(); | 1011 | { |
909 | } | 1012 | m_log.ErrorFormat( |
1013 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
1014 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
910 | 1015 | ||
911 | // Fire after attach, so we don't get messy perms dialogs | 1016 | // Make sure the object doesn't stick around and bail |
912 | // 4 == AttachedRez | 1017 | sp.RemoveAttachment(objatt); |
913 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | 1018 | m_scene.DeleteSceneObject(objatt, false); |
914 | objatt.ResumeScripts(); | 1019 | return null; |
1020 | } | ||
915 | 1021 | ||
916 | // Do this last so that event listeners have access to all the effects of the attachment | 1022 | if (tainted) |
917 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | 1023 | objatt.HasGroupChanged = true; |
918 | 1024 | ||
919 | return objatt; | 1025 | return objatt; |
920 | } | ||
921 | else | ||
922 | { | ||
923 | m_log.WarnFormat( | ||
924 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
925 | itemID, sp.Name, attachmentPt); | ||
926 | } | ||
927 | } | ||
928 | |||
929 | return null; | ||
930 | } | 1026 | } |
931 | 1027 | ||
932 | /// <summary> | 1028 | /// <summary> |
@@ -963,9 +1059,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
963 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); | 1059 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID); |
964 | if (changed && m_scene.AvatarFactory != null) | 1060 | if (changed && m_scene.AvatarFactory != null) |
965 | { | 1061 | { |
966 | // m_log.DebugFormat( | 1062 | if (DebugLevel > 0) |
967 | // "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", | 1063 | m_log.DebugFormat( |
968 | // sp.Name, att.Name, AttachmentPt); | 1064 | "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", |
1065 | sp.Name, att.Name, AttachmentPt); | ||
969 | 1066 | ||
970 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 1067 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
971 | } | 1068 | } |
@@ -980,9 +1077,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
980 | if (!Enabled) | 1077 | if (!Enabled) |
981 | return null; | 1078 | return null; |
982 | 1079 | ||
983 | // m_log.DebugFormat( | 1080 | if (DebugLevel > 0) |
984 | // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", | 1081 | m_log.DebugFormat( |
985 | // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | 1082 | "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", |
1083 | (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); | ||
986 | 1084 | ||
987 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1085 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
988 | 1086 | ||
@@ -1013,9 +1111,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1013 | 1111 | ||
1014 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 1112 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
1015 | { | 1113 | { |
1016 | // m_log.DebugFormat( | 1114 | if (DebugLevel > 0) |
1017 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 1115 | m_log.DebugFormat( |
1018 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); | 1116 | "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", |
1117 | objectLocalID, remoteClient.Name, AttachmentPt, silent); | ||
1019 | 1118 | ||
1020 | if (!Enabled) | 1119 | if (!Enabled) |
1021 | return; | 1120 | return; |
@@ -1048,11 +1147,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1048 | AttachmentPt &= 0x7f; | 1147 | AttachmentPt &= 0x7f; |
1049 | 1148 | ||
1050 | // Calls attach with a Zero position | 1149 | // Calls attach with a Zero position |
1051 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false, append)) | 1150 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, false, append)) |
1052 | { | 1151 | { |
1053 | // m_log.Debug( | 1152 | if (DebugLevel > 0) |
1054 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | 1153 | m_log.Debug( |
1055 | // + ", AttachmentPoint: " + AttachmentPt); | 1154 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId |
1155 | + ", AttachmentPoint: " + AttachmentPt); | ||
1056 | 1156 | ||
1057 | // Save avatar attachment information | 1157 | // Save avatar attachment information |
1058 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | 1158 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); |
@@ -1084,17 +1184,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1084 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1184 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1085 | if (sp != null) | 1185 | if (sp != null) |
1086 | { | 1186 | { |
1087 | lock (sp.AttachmentsSyncLock) | 1187 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
1188 | |||
1189 | foreach (SceneObjectGroup group in attachments) | ||
1088 | { | 1190 | { |
1089 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 1191 | if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) |
1090 | |||
1091 | foreach (SceneObjectGroup group in attachments) | ||
1092 | { | 1192 | { |
1093 | if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) | 1193 | DetachSingleAttachmentToInv(sp, group); |
1094 | { | 1194 | return; |
1095 | DetachSingleAttachmentToInv(sp, group); | ||
1096 | return; | ||
1097 | } | ||
1098 | } | 1195 | } |
1099 | } | 1196 | } |
1100 | } | 1197 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 545aeda..1a38619 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
130 | config.AddConfig("Modules"); | 130 | config.AddConfig("Modules"); |
131 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 131 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
132 | 132 | ||
133 | modules.Add(new AttachmentsModule()); | 133 | AttachmentsModule attMod = new AttachmentsModule(); |
134 | attMod.DebugLevel = 1; | ||
135 | modules.Add(attMod); | ||
134 | modules.Add(new BasicInventoryAccessModule()); | 136 | modules.Add(new BasicInventoryAccessModule()); |
135 | } | 137 | } |
136 | 138 | ||
@@ -197,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
197 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); | 199 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
198 | 200 | ||
199 | m_numberOfAttachEventsFired = 0; | 201 | m_numberOfAttachEventsFired = 0; |
200 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false); | 202 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false); |
201 | 203 | ||
202 | // Check status on scene presence | 204 | // Check status on scene presence |
203 | Assert.That(sp.HasAttachments(), Is.True); | 205 | Assert.That(sp.HasAttachments(), Is.True); |
@@ -228,6 +230,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
228 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | 230 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); |
229 | } | 231 | } |
230 | 232 | ||
233 | [Test] | ||
234 | public void TestWearAttachmentFromGround() | ||
235 | { | ||
236 | TestHelpers.InMethod(); | ||
237 | // TestHelpers.EnableLogging(); | ||
238 | |||
239 | Scene scene = CreateTestScene(); | ||
240 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
241 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
242 | |||
243 | SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID); | ||
244 | |||
245 | { | ||
246 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); | ||
247 | |||
248 | m_numberOfAttachEventsFired = 0; | ||
249 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false, false); | ||
250 | |||
251 | // Check status on scene presence | ||
252 | Assert.That(sp.HasAttachments(), Is.True); | ||
253 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
254 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
255 | SceneObjectGroup attSo = attachments[0]; | ||
256 | Assert.That(attSo.Name, Is.EqualTo(so.Name)); | ||
257 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
258 | Assert.That(attSo.IsAttachment); | ||
259 | Assert.That(attSo.UsesPhysics, Is.False); | ||
260 | Assert.That(attSo.IsTemporary, Is.False); | ||
261 | |||
262 | // Check item status | ||
263 | Assert.That( | ||
264 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
265 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
266 | |||
267 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
268 | Assert.That(attachmentItem, Is.Not.Null); | ||
269 | Assert.That(attachmentItem.Name, Is.EqualTo(so.Name)); | ||
270 | |||
271 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
272 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
273 | |||
274 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2)); | ||
275 | |||
276 | // Check events | ||
277 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
278 | } | ||
279 | |||
280 | // Test wearing a different attachment from the ground. | ||
281 | { | ||
282 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false); | ||
283 | |||
284 | // Check status on scene presence | ||
285 | Assert.That(sp.HasAttachments(), Is.True); | ||
286 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
287 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
288 | SceneObjectGroup attSo = attachments[0]; | ||
289 | Assert.That(attSo.Name, Is.EqualTo(so2.Name)); | ||
290 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
291 | Assert.That(attSo.IsAttachment); | ||
292 | Assert.That(attSo.UsesPhysics, Is.False); | ||
293 | Assert.That(attSo.IsTemporary, Is.False); | ||
294 | |||
295 | // Check item status | ||
296 | Assert.That( | ||
297 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
298 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
299 | |||
300 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
301 | Assert.That(attachmentItem, Is.Not.Null); | ||
302 | Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); | ||
303 | |||
304 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
305 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
306 | |||
307 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
308 | |||
309 | // Check events | ||
310 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
311 | } | ||
312 | |||
313 | // Test rewearing an already worn attachment from ground. Nothing should happen. | ||
314 | { | ||
315 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false); | ||
316 | |||
317 | // Check status on scene presence | ||
318 | Assert.That(sp.HasAttachments(), Is.True); | ||
319 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
320 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
321 | SceneObjectGroup attSo = attachments[0]; | ||
322 | Assert.That(attSo.Name, Is.EqualTo(so2.Name)); | ||
323 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
324 | Assert.That(attSo.IsAttachment); | ||
325 | Assert.That(attSo.UsesPhysics, Is.False); | ||
326 | Assert.That(attSo.IsTemporary, Is.False); | ||
327 | |||
328 | // Check item status | ||
329 | Assert.That( | ||
330 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
331 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
332 | |||
333 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
334 | Assert.That(attachmentItem, Is.Not.Null); | ||
335 | Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); | ||
336 | |||
337 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
338 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
339 | |||
340 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
341 | |||
342 | // Check events | ||
343 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
344 | } | ||
345 | } | ||
346 | |||
231 | /// <summary> | 347 | /// <summary> |
232 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. | 348 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. |
233 | /// </summary> | 349 | /// </summary> |
@@ -254,7 +370,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
254 | sp2.AbsolutePosition = new Vector3(0, 0, 0); | 370 | sp2.AbsolutePosition = new Vector3(0, 0, 0); |
255 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); | 371 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); |
256 | 372 | ||
257 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false); | 373 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false); |
258 | 374 | ||
259 | Assert.That(sp.HasAttachments(), Is.False); | 375 | Assert.That(sp.HasAttachments(), Is.False); |
260 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 376 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); |
@@ -275,29 +391,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
275 | 391 | ||
276 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | 392 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
277 | 393 | ||
278 | m_numberOfAttachEventsFired = 0; | 394 | { |
279 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 395 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
280 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 396 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
281 | 397 | ||
282 | // Check scene presence status | 398 | // Check scene presence status |
283 | Assert.That(sp.HasAttachments(), Is.True); | 399 | Assert.That(sp.HasAttachments(), Is.True); |
284 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 400 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
285 | Assert.That(attachments.Count, Is.EqualTo(1)); | 401 | Assert.That(attachments.Count, Is.EqualTo(1)); |
286 | SceneObjectGroup attSo = attachments[0]; | 402 | SceneObjectGroup attSo = attachments[0]; |
287 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); | 403 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
288 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 404 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
289 | Assert.That(attSo.IsAttachment); | 405 | Assert.That(attSo.IsAttachment); |
290 | Assert.That(attSo.UsesPhysics, Is.False); | 406 | Assert.That(attSo.UsesPhysics, Is.False); |
291 | Assert.That(attSo.IsTemporary, Is.False); | 407 | Assert.That(attSo.IsTemporary, Is.False); |
408 | |||
409 | // Check appearance status | ||
410 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
411 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
412 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
413 | |||
414 | // Check events | ||
415 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
416 | } | ||
417 | |||
418 | // Test attaching an already attached attachment | ||
419 | { | ||
420 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
421 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
292 | 422 | ||
293 | // Check appearance status | 423 | // Check scene presence status |
294 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | 424 | Assert.That(sp.HasAttachments(), Is.True); |
295 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | 425 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
426 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
427 | SceneObjectGroup attSo = attachments[0]; | ||
428 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); | ||
429 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | ||
430 | Assert.That(attSo.IsAttachment); | ||
431 | Assert.That(attSo.UsesPhysics, Is.False); | ||
432 | Assert.That(attSo.IsTemporary, Is.False); | ||
433 | |||
434 | // Check appearance status | ||
435 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
436 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
437 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
438 | |||
439 | // Check events | ||
440 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
441 | } | ||
442 | } | ||
296 | 443 | ||
297 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 444 | /// <summary> |
445 | /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point | ||
446 | /// </summary> | ||
447 | [Test] | ||
448 | public void TestWearAttachmentFromInventory() | ||
449 | { | ||
450 | TestHelpers.InMethod(); | ||
451 | // TestHelpers.EnableLogging(); | ||
298 | 452 | ||
299 | // Check events | 453 | Scene scene = CreateTestScene(); |
300 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | 454 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
455 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
456 | |||
457 | InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20); | ||
458 | InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21); | ||
459 | |||
460 | { | ||
461 | m_numberOfAttachEventsFired = 0; | ||
462 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default); | ||
463 | |||
464 | // default attachment point is currently the left hand. | ||
465 | Assert.That(sp.HasAttachments(), Is.True); | ||
466 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
467 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
468 | SceneObjectGroup attSo = attachments[0]; | ||
469 | Assert.That(attSo.Name, Is.EqualTo(attItem1.Name)); | ||
470 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
471 | Assert.That(attSo.IsAttachment); | ||
472 | |||
473 | // Check appearance status | ||
474 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
475 | Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
476 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
477 | |||
478 | // Check events | ||
479 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
480 | } | ||
481 | |||
482 | // Test wearing a second attachment at the same position | ||
483 | // Until multiple attachments at one point is implemented, this will remove the first attachment | ||
484 | // This test relies on both attachments having the same default attachment point (in this case LeftHand | ||
485 | // since none other has been set). | ||
486 | { | ||
487 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); | ||
488 | |||
489 | // default attachment point is currently the left hand. | ||
490 | Assert.That(sp.HasAttachments(), Is.True); | ||
491 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
492 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
493 | SceneObjectGroup attSo = attachments[0]; | ||
494 | Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); | ||
495 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
496 | Assert.That(attSo.IsAttachment); | ||
497 | |||
498 | // Check appearance status | ||
499 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
500 | Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
501 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
502 | |||
503 | // Check events | ||
504 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
505 | } | ||
506 | |||
507 | // Test wearing an already attached attachment | ||
508 | { | ||
509 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); | ||
510 | |||
511 | // default attachment point is currently the left hand. | ||
512 | Assert.That(sp.HasAttachments(), Is.True); | ||
513 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
514 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
515 | SceneObjectGroup attSo = attachments[0]; | ||
516 | Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); | ||
517 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
518 | Assert.That(attSo.IsAttachment); | ||
519 | |||
520 | // Check appearance status | ||
521 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
522 | Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
523 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
524 | |||
525 | // Check events | ||
526 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
527 | } | ||
301 | } | 528 | } |
302 | 529 | ||
303 | /// <summary> | 530 | /// <summary> |
@@ -503,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
503 | public void TestRezAttachmentsOnAvatarEntrance() | 730 | public void TestRezAttachmentsOnAvatarEntrance() |
504 | { | 731 | { |
505 | TestHelpers.InMethod(); | 732 | TestHelpers.InMethod(); |
506 | // log4net.Config.XmlConfigurator.Configure(); | 733 | // TestHelpers.EnableLogging(); |
507 | 734 | ||
508 | Scene scene = CreateTestScene(); | 735 | Scene scene = CreateTestScene(); |
509 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | 736 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
@@ -604,7 +831,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
604 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | 831 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); |
605 | 832 | ||
606 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | 833 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); |
607 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); | 834 | |
835 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | ||
836 | TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); | ||
837 | List<TestClient> destinationTestClients = new List<TestClient>(); | ||
838 | EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); | ||
839 | |||
840 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); | ||
608 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | 841 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); |
609 | 842 | ||
610 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | 843 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); |
@@ -623,7 +856,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
623 | teleportLookAt, | 856 | teleportLookAt, |
624 | (uint)TeleportFlags.ViaLocation); | 857 | (uint)TeleportFlags.ViaLocation); |
625 | 858 | ||
626 | ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); | 859 | destinationTestClients[0].CompleteMovement(); |
627 | 860 | ||
628 | // Check attachments have made it into sceneB | 861 | // Check attachments have made it into sceneB |
629 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); | 862 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 1adff7e..bc79944 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes; | |||
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | 41 | ||
42 | using Mono.Addins; | 42 | using Mono.Addins; |
43 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
43 | 44 | ||
44 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | 45 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory |
45 | { | 46 | { |
@@ -322,6 +323,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
322 | 323 | ||
323 | if (asset != null) | 324 | if (asset != null) |
324 | { | 325 | { |
326 | // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars | ||
327 | asset.ID = asset.FullID.ToString(); | ||
328 | |||
325 | asset.Temporary = false; | 329 | asset.Temporary = false; |
326 | asset.Local = false; | 330 | asset.Local = false; |
327 | m_scene.AssetService.Store(asset); | 331 | m_scene.AssetService.Store(asset); |
@@ -358,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
358 | 362 | ||
359 | public void QueueAppearanceSave(UUID agentid) | 363 | public void QueueAppearanceSave(UUID agentid) |
360 | { | 364 | { |
361 | // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); | 365 | // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); |
362 | 366 | ||
363 | // 10000 ticks per millisecond, 1000 milliseconds per second | 367 | // 10000 ticks per millisecond, 1000 milliseconds per second |
364 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); | 368 | long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); |
@@ -655,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
655 | return; | 659 | return; |
656 | } | 660 | } |
657 | 661 | ||
658 | // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); | 662 | // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); |
659 | 663 | ||
660 | // This could take awhile since it needs to pull inventory | 664 | // This could take awhile since it needs to pull inventory |
661 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape | 665 | // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape |
@@ -664,6 +668,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
664 | // multiple save requests. | 668 | // multiple save requests. |
665 | SetAppearanceAssets(sp.UUID, sp.Appearance); | 669 | SetAppearanceAssets(sp.UUID, sp.Appearance); |
666 | 670 | ||
671 | // List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | ||
672 | // foreach (AvatarAttachment att in attachments) | ||
673 | // { | ||
674 | // m_log.DebugFormat( | ||
675 | // "[AVFACTORY]: For {0} saving attachment {1} at point {2}", | ||
676 | // sp.Name, att.ItemID, att.AttachPoint); | ||
677 | // } | ||
678 | |||
667 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | 679 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); |
668 | 680 | ||
669 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. | 681 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. |
@@ -1087,7 +1099,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1087 | } | 1099 | } |
1088 | 1100 | ||
1089 | bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); | 1101 | bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); |
1090 | outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); | 1102 | outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete"); |
1091 | } | 1103 | } |
1092 | } | 1104 | } |
1093 | } | 1105 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index e21547c..f090e15 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | |||
@@ -39,7 +39,7 @@ using OpenSim.Tests.Common.Mock; | |||
39 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | 39 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory |
40 | { | 40 | { |
41 | [TestFixture] | 41 | [TestFixture] |
42 | public class AvatarFactoryModuleTests | 42 | public class AvatarFactoryModuleTests : OpenSimTestCase |
43 | { | 43 | { |
44 | /// <summary> | 44 | /// <summary> |
45 | /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. | 45 | /// Only partial right now since we don't yet test that it's ended up in the avatar appearance service. |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 4c3f1cc..174642d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -256,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
256 | // If camera is moved into client, then camera position can be used | 256 | // If camera is moved into client, then camera position can be used |
257 | // MT: No, it can't, as chat is heard from the avatar position, not | 257 | // MT: No, it can't, as chat is heard from the avatar position, not |
258 | // the camera position. | 258 | // the camera position. |
259 | s.ForEachRootScenePresence( | 259 | s.ForEachScenePresence( |
260 | delegate(ScenePresence presence) | 260 | delegate(ScenePresence presence) |
261 | { | 261 | { |
262 | if (destination != UUID.Zero && presence.UUID != destination) | 262 | if (destination != UUID.Zero && presence.UUID != destination) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index 5ec0ea9..b44a5c9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs | |||
@@ -36,6 +36,7 @@ using OpenSim.Region.Framework.Interfaces; | |||
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
38 | using Mono.Addins; | 38 | using Mono.Addins; |
39 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
39 | 40 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.Friends | 41 | namespace OpenSim.Region.CoreModules.Avatar.Friends |
41 | { | 42 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 7a197f7..961117e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | |||
@@ -40,7 +40,7 @@ using OpenSim.Tests.Common.Mock; | |||
40 | namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | 40 | namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests |
41 | { | 41 | { |
42 | [TestFixture] | 42 | [TestFixture] |
43 | public class FriendsModuleTests | 43 | public class FriendsModuleTests : OpenSimTestCase |
44 | { | 44 | { |
45 | private FriendsModule m_fm; | 45 | private FriendsModule m_fm; |
46 | private TestScene m_scene; | 46 | private TestScene m_scene; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 9fa9be1..fa8c3f3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | |||
@@ -67,9 +67,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
67 | protected Scene m_scene; | 67 | protected Scene m_scene; |
68 | protected IDialogModule m_dialogModule; | 68 | protected IDialogModule m_dialogModule; |
69 | 69 | ||
70 | protected Dictionary<UUID, string> m_capsDict = | ||
71 | new Dictionary<UUID, string>(); | ||
72 | |||
73 | protected IDialogModule DialogModule | 70 | protected IDialogModule DialogModule |
74 | { | 71 | { |
75 | get | 72 | get |
@@ -91,7 +88,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
91 | m_scene.RegisterModuleInterface<IGodsModule>(this); | 88 | m_scene.RegisterModuleInterface<IGodsModule>(this); |
92 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 89 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
93 | m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 90 | m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
94 | m_scene.EventManager.OnClientClosed += OnClientClosed; | ||
95 | scene.EventManager.OnIncomingInstantMessage += | 91 | scene.EventManager.OnIncomingInstantMessage += |
96 | OnIncomingInstantMessage; | 92 | OnIncomingInstantMessage; |
97 | } | 93 | } |
@@ -127,15 +123,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
127 | client.OnRequestGodlikePowers -= RequestGodlikePowers; | 123 | client.OnRequestGodlikePowers -= RequestGodlikePowers; |
128 | } | 124 | } |
129 | 125 | ||
130 | private void OnClientClosed(UUID agentID, Scene scene) | ||
131 | { | ||
132 | m_capsDict.Remove(agentID); | ||
133 | } | ||
134 | |||
135 | private void OnRegisterCaps(UUID agentID, Caps caps) | 126 | private void OnRegisterCaps(UUID agentID, Caps caps) |
136 | { | 127 | { |
137 | string uri = "/CAPS/" + UUID.Random(); | 128 | string uri = "/CAPS/" + UUID.Random(); |
138 | m_capsDict[agentID] = uri; | ||
139 | 129 | ||
140 | caps.RegisterHandler("UntrustedSimulatorMessage", | 130 | caps.RegisterHandler("UntrustedSimulatorMessage", |
141 | new RestStreamHandler("POST", uri, | 131 | new RestStreamHandler("POST", uri, |
@@ -288,8 +278,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
288 | if (sp.IsChildAgent) | 278 | if (sp.IsChildAgent) |
289 | return; | 279 | return; |
290 | sp.ControllingClient.Kick(reason); | 280 | sp.ControllingClient.Kick(reason); |
291 | sp.MakeChildAgent(); | 281 | sp.Scene.IncomingCloseAgent(sp.UUID, true); |
292 | sp.ControllingClient.Close(); | ||
293 | } | 282 | } |
294 | 283 | ||
295 | private void OnIncomingInstantMessage(GridInstantMessage msg) | 284 | private void OnIncomingInstantMessage(GridInstantMessage msg) |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index cc266df..1627f6c 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | |||
@@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
153 | if (sp != null && !sp.IsChildAgent) | 153 | if (sp != null && !sp.IsChildAgent) |
154 | { | 154 | { |
155 | // Local message | 155 | // Local message |
156 | m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); | 156 | // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID); |
157 | 157 | ||
158 | sp.ControllingClient.SendInstantMessage(im); | 158 | sp.ControllingClient.SendInstantMessage(im); |
159 | 159 | ||
@@ -166,14 +166,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
166 | // try child avatar second | 166 | // try child avatar second |
167 | foreach (Scene scene in m_Scenes) | 167 | foreach (Scene scene in m_Scenes) |
168 | { | 168 | { |
169 | //m_log.DebugFormat( | 169 | // m_log.DebugFormat( |
170 | // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); | 170 | // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); |
171 | 171 | ||
172 | ScenePresence sp = scene.GetScenePresence(toAgentID); | 172 | ScenePresence sp = scene.GetScenePresence(toAgentID); |
173 | if (sp != null) | 173 | if (sp != null) |
174 | { | 174 | { |
175 | // Local message | 175 | // Local message |
176 | m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); | 176 | // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID); |
177 | 177 | ||
178 | sp.ControllingClient.SendInstantMessage(im); | 178 | sp.ControllingClient.SendInstantMessage(im); |
179 | 179 | ||
@@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); | 186 | // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); |
187 | 187 | ||
188 | SendGridInstantMessageViaXMLRPC(im, result); | 188 | SendGridInstantMessageViaXMLRPC(im, result); |
189 | } | 189 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 3a44cc5..2d46276 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -189,20 +189,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
189 | { | 189 | { |
190 | foreach (GridInstantMessage im in msglist) | 190 | foreach (GridInstantMessage im in msglist) |
191 | { | 191 | { |
192 | // client.SendInstantMessage(im); | 192 | if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) |
193 | 193 | // send it directly or else the item will be given twice | |
194 | // Send through scene event manager so all modules get a chance | 194 | client.SendInstantMessage(im); |
195 | // to look at this message before it gets delivered. | 195 | else |
196 | // | 196 | { |
197 | // Needed for proper state management for stored group | 197 | // Send through scene event manager so all modules get a chance |
198 | // invitations | 198 | // to look at this message before it gets delivered. |
199 | // | 199 | // |
200 | 200 | // Needed for proper state management for stored group | |
201 | im.offline = 1; | 201 | // invitations |
202 | 202 | // | |
203 | Scene s = FindScene(client.AgentId); | 203 | |
204 | if (s != null) | 204 | im.offline = 1; |
205 | s.EventManager.TriggerIncomingInstantMessage(im); | 205 | |
206 | Scene s = FindScene(client.AgentId); | ||
207 | if (s != null) | ||
208 | s.EventManager.TriggerIncomingInstantMessage(im); | ||
209 | } | ||
206 | } | 210 | } |
207 | } | 211 | } |
208 | } | 212 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index dc2b0e0..659b178 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
161 | string filePath = "ERROR"; | 161 | string filePath = "ERROR"; |
162 | 162 | ||
163 | List<InventoryFolderBase> folderCandidates | 163 | List<InventoryFolderBase> folderCandidates |
164 | = InventoryArchiveUtils.FindFolderByPath( | 164 | = InventoryArchiveUtils.FindFoldersByPath( |
165 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); | 165 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); |
166 | 166 | ||
167 | if (folderCandidates.Count == 0) | 167 | if (folderCandidates.Count == 0) |
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
296 | // iar name and try to find that instead. | 296 | // iar name and try to find that instead. |
297 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | 297 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); |
298 | List<InventoryFolderBase> folderCandidates | 298 | List<InventoryFolderBase> folderCandidates |
299 | = InventoryArchiveUtils.FindFolderByPath( | 299 | = InventoryArchiveUtils.FindFoldersByPath( |
300 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); | 300 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); |
301 | 301 | ||
302 | if (folderCandidates.Count != 0) | 302 | if (folderCandidates.Count != 0) |
@@ -487,6 +487,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
487 | { | 487 | { |
488 | // m_log.DebugFormat( | 488 | // m_log.DebugFormat( |
489 | // "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); | 489 | // "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); |
490 | |||
491 | if (coa.Objects.Count == 0) | ||
492 | { | ||
493 | m_log.WarnFormat( | ||
494 | "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components", | ||
495 | assetId); | ||
496 | return false; | ||
497 | } | ||
490 | 498 | ||
491 | sceneObjects.AddRange(coa.Objects); | 499 | sceneObjects.AddRange(coa.Objects); |
492 | } | 500 | } |
@@ -495,7 +503,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
495 | SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 503 | SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
496 | 504 | ||
497 | if (deserializedObject != null) | 505 | if (deserializedObject != null) |
506 | { | ||
498 | sceneObjects.Add(deserializedObject); | 507 | sceneObjects.Add(deserializedObject); |
508 | } | ||
509 | else | ||
510 | { | ||
511 | m_log.WarnFormat( | ||
512 | "[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed", | ||
513 | assetId); | ||
514 | |||
515 | return false; | ||
516 | } | ||
499 | } | 517 | } |
500 | 518 | ||
501 | foreach (SceneObjectGroup sog in sceneObjects) | 519 | foreach (SceneObjectGroup sog in sceneObjects) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index 0d90a15..dbaf2aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs | |||
@@ -52,13 +52,82 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
52 | /// <summary> | 52 | /// <summary> |
53 | /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder | 53 | /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder |
54 | /// </summary> | 54 | /// </summary> |
55 | /// <remarks> | ||
56 | /// This method does not handle paths that contain multiple delimitors | ||
57 | /// | ||
58 | /// FIXME: We have no way of distinguishing folders with the same path | ||
55 | /// | 59 | /// |
60 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | ||
61 | /// </remarks> | ||
62 | /// <param name="inventoryService"> | ||
63 | /// Inventory service to query | ||
64 | /// </param> | ||
65 | /// <param name="userId"> | ||
66 | /// User id to search | ||
67 | /// </param> | ||
68 | /// <param name="path"> | ||
69 | /// The path to the required folder. | ||
70 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | ||
71 | /// </param> | ||
72 | /// <returns>The folder found. Please note that if there are multiple folders with the same name then an | ||
73 | /// unspecified one will be returned. If no such folder eixsts then null is returned</returns> | ||
74 | public static InventoryFolderBase FindFolderByPath( | ||
75 | IInventoryService inventoryService, UUID userId, string path) | ||
76 | { | ||
77 | List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, userId, path); | ||
78 | |||
79 | if (folders.Count == 0) | ||
80 | return null; | ||
81 | else | ||
82 | return folders[0]; | ||
83 | } | ||
84 | |||
85 | /// <summary> | ||
86 | /// Find a folder given a PATH_DELIMITER delimited path starting from a given folder | ||
87 | /// </summary> | ||
88 | /// <remarks> | ||
56 | /// This method does not handle paths that contain multiple delimitors | 89 | /// This method does not handle paths that contain multiple delimitors |
57 | /// | 90 | /// |
58 | /// FIXME: We have no way of distinguishing folders with the same path | 91 | /// FIXME: We have no way of distinguishing folders with the same path |
59 | /// | 92 | /// |
60 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | 93 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. |
94 | /// </remarks> | ||
95 | /// <param name="inventoryService"> | ||
96 | /// Inventory service to query | ||
97 | /// </param> | ||
98 | /// <param name="startFolder"> | ||
99 | /// The folder from which the path starts | ||
100 | /// </param> | ||
101 | /// <param name="path"> | ||
102 | /// The path to the required folder. | ||
103 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | ||
104 | /// </param> | ||
105 | /// <returns>The folder found. Please note that if there are multiple folders with the same name then an | ||
106 | /// unspecified one will be returned. If no such folder eixsts then null is returned</returns> | ||
107 | public static InventoryFolderBase FindFolderByPath( | ||
108 | IInventoryService inventoryService, InventoryFolderBase startFolder, string path) | ||
109 | { | ||
110 | if (null == startFolder) | ||
111 | return null; | ||
112 | |||
113 | List<InventoryFolderBase> folders = FindFoldersByPath(inventoryService, startFolder, path); | ||
114 | |||
115 | if (folders.Count == 0) | ||
116 | return null; | ||
117 | else | ||
118 | return folders[0]; | ||
119 | } | ||
120 | |||
121 | /// <summary> | ||
122 | /// Find a set of folders given a PATH_DELIMITER delimited path starting from a user's root folder | ||
123 | /// </summary> | ||
124 | /// <remarks> | ||
125 | /// This method does not handle paths that contain multiple delimitors | ||
126 | /// | ||
127 | /// FIXME: We have no way of distinguishing folders with the same path | ||
61 | /// | 128 | /// |
129 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | ||
130 | /// </remarks> | ||
62 | /// <param name="inventoryService"> | 131 | /// <param name="inventoryService"> |
63 | /// Inventory service to query | 132 | /// Inventory service to query |
64 | /// </param> | 133 | /// </param> |
@@ -70,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
70 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | 139 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. |
71 | /// </param> | 140 | /// </param> |
72 | /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> | 141 | /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> |
73 | public static List<InventoryFolderBase> FindFolderByPath( | 142 | public static List<InventoryFolderBase> FindFoldersByPath( |
74 | IInventoryService inventoryService, UUID userId, string path) | 143 | IInventoryService inventoryService, UUID userId, string path) |
75 | { | 144 | { |
76 | InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); | 145 | InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); |
@@ -78,19 +147,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
78 | if (null == rootFolder) | 147 | if (null == rootFolder) |
79 | return new List<InventoryFolderBase>(); | 148 | return new List<InventoryFolderBase>(); |
80 | 149 | ||
81 | return FindFolderByPath(inventoryService, rootFolder, path); | 150 | return FindFoldersByPath(inventoryService, rootFolder, path); |
82 | } | 151 | } |
83 | 152 | ||
84 | /// <summary> | 153 | /// <summary> |
85 | /// Find a folder given a PATH_DELIMITER delimited path starting from this folder | 154 | /// Find a set of folders given a PATH_DELIMITER delimited path starting from this folder |
86 | /// </summary> | 155 | /// </summary> |
87 | /// | 156 | /// <remarks> |
88 | /// This method does not handle paths that contain multiple delimitors | 157 | /// This method does not handle paths that contain multiple delimitors |
89 | /// | 158 | /// |
90 | /// FIXME: We have no way of distinguishing folders with the same path. | 159 | /// FIXME: We have no way of distinguishing folders with the same path. |
91 | /// | 160 | /// |
92 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. | 161 | /// FIXME: Delimitors which occur in names themselves are not currently escapable. |
93 | /// | 162 | /// </remarks> |
94 | /// <param name="inventoryService"> | 163 | /// <param name="inventoryService"> |
95 | /// Inventory service to query | 164 | /// Inventory service to query |
96 | /// </param> | 165 | /// </param> |
@@ -102,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
102 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. | 171 | /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. |
103 | /// </param> | 172 | /// </param> |
104 | /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> | 173 | /// <returns>An empty list if the folder is not found, otherwise a list of all folders that match the name</returns> |
105 | public static List<InventoryFolderBase> FindFolderByPath( | 174 | public static List<InventoryFolderBase> FindFoldersByPath( |
106 | IInventoryService inventoryService, InventoryFolderBase startFolder, string path) | 175 | IInventoryService inventoryService, InventoryFolderBase startFolder, string path) |
107 | { | 176 | { |
108 | List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>(); | 177 | List<InventoryFolderBase> foundFolders = new List<InventoryFolderBase>(); |
@@ -133,12 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
133 | 202 | ||
134 | InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); | 203 | InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); |
135 | 204 | ||
205 | // m_log.DebugFormat( | ||
206 | // "Found {0} folders in {1} for {2}", contents.Folders.Count, startFolder.Name, startFolder.Owner); | ||
207 | |||
136 | foreach (InventoryFolderBase folder in contents.Folders) | 208 | foreach (InventoryFolderBase folder in contents.Folders) |
137 | { | 209 | { |
138 | if (folder.Name == components[0]) | 210 | if (folder.Name == components[0]) |
139 | { | 211 | { |
140 | if (components.Length > 1) | 212 | if (components.Length > 1) |
141 | foundFolders.AddRange(FindFolderByPath(inventoryService, folder, components[1])); | 213 | foundFolders.AddRange(FindFoldersByPath(inventoryService, folder, components[1])); |
142 | else | 214 | else |
143 | foundFolders.Add(folder); | 215 | foundFolders.Add(folder); |
144 | } | 216 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index d0e88f6..4ec8ae7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
124 | SaveAssets = true; | 124 | SaveAssets = true; |
125 | } | 125 | } |
126 | 126 | ||
127 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) | 127 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut) |
128 | { | 128 | { |
129 | Exception reportedException = null; | 129 | Exception reportedException = null; |
130 | bool succeeded = true; | 130 | bool succeeded = true; |
@@ -143,6 +143,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
143 | m_saveStream.Close(); | 143 | m_saveStream.Close(); |
144 | } | 144 | } |
145 | 145 | ||
146 | if (timedOut) | ||
147 | { | ||
148 | succeeded = false; | ||
149 | reportedException = new Exception("Loading assets timed out"); | ||
150 | } | ||
151 | |||
146 | m_module.TriggerInventoryArchiveSaved( | 152 | m_module.TriggerInventoryArchiveSaved( |
147 | m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); | 153 | m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); |
148 | } | 154 | } |
@@ -266,6 +272,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
266 | saveFolderContentsOnly = true; | 272 | saveFolderContentsOnly = true; |
267 | maxComponentIndex--; | 273 | maxComponentIndex--; |
268 | } | 274 | } |
275 | else if (maxComponentIndex == -1) | ||
276 | { | ||
277 | // If the user has just specified "/", then don't save the root "My Inventory" folder. This is | ||
278 | // more intuitive then requiring the user to specify "/*" for this. | ||
279 | saveFolderContentsOnly = true; | ||
280 | } | ||
269 | 281 | ||
270 | m_invPath = String.Empty; | 282 | m_invPath = String.Empty; |
271 | for (int i = 0; i <= maxComponentIndex; i++) | 283 | for (int i = 0; i <= maxComponentIndex; i++) |
@@ -283,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
283 | { | 295 | { |
284 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); | 296 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); |
285 | List<InventoryFolderBase> candidateFolders | 297 | List<InventoryFolderBase> candidateFolders |
286 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); | 298 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath); |
287 | if (candidateFolders.Count > 0) | 299 | if (candidateFolders.Count > 0) |
288 | inventoryFolder = candidateFolders[0]; | 300 | inventoryFolder = candidateFolders[0]; |
289 | } | 301 | } |
@@ -350,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
350 | { | 362 | { |
351 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); | 363 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); |
352 | 364 | ||
353 | ReceivedAllAssets(new List<UUID>(), new List<UUID>()); | 365 | ReceivedAllAssets(new List<UUID>(), new List<UUID>(), false); |
354 | } | 366 | } |
355 | } | 367 | } |
356 | catch (Exception) | 368 | catch (Exception) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index 6eb3605..95f562e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs | |||
@@ -48,125 +48,9 @@ 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 PathTests : InventoryArchiveTestCase | 51 | public class InventoryArchiveLoadPathTests : InventoryArchiveTestCase |
52 | { | 52 | { |
53 | /// <summary> | 53 | /// <summary> |
54 | /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive | ||
55 | /// (subject to change since there is no fixed format yet). | ||
56 | /// </summary> | ||
57 | [Test] | ||
58 | public void TestSavePathToIarV0_1() | ||
59 | { | ||
60 | TestHelpers.InMethod(); | ||
61 | // log4net.Config.XmlConfigurator.Configure(); | ||
62 | |||
63 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | ||
64 | |||
65 | Scene scene = new SceneHelpers().SetupScene(); | ||
66 | SceneHelpers.SetupSceneModules(scene, archiverModule); | ||
67 | |||
68 | // Create user | ||
69 | string userFirstName = "Jock"; | ||
70 | string userLastName = "Stirrup"; | ||
71 | string userPassword = "troll"; | ||
72 | UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); | ||
73 | UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); | ||
74 | |||
75 | // Create asset | ||
76 | SceneObjectGroup object1; | ||
77 | SceneObjectPart part1; | ||
78 | { | ||
79 | string partName = "My Little Dog Object"; | ||
80 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); | ||
81 | PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); | ||
82 | Vector3 groupPosition = new Vector3(10, 20, 30); | ||
83 | Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); | ||
84 | Vector3 offsetPosition = new Vector3(5, 10, 15); | ||
85 | |||
86 | part1 = new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition); | ||
87 | part1.Name = partName; | ||
88 | |||
89 | object1 = new SceneObjectGroup(part1); | ||
90 | scene.AddNewSceneObject(object1, false); | ||
91 | } | ||
92 | |||
93 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | ||
94 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | ||
95 | scene.AssetService.Store(asset1); | ||
96 | |||
97 | // Create item | ||
98 | UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); | ||
99 | InventoryItemBase item1 = new InventoryItemBase(); | ||
100 | item1.Name = "My Little Dog"; | ||
101 | item1.AssetID = asset1.FullID; | ||
102 | item1.ID = item1Id; | ||
103 | InventoryFolderBase objsFolder | ||
104 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; | ||
105 | item1.Folder = objsFolder.ID; | ||
106 | scene.AddInventoryItem(item1); | ||
107 | |||
108 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
109 | archiverModule.OnInventoryArchiveSaved += SaveCompleted; | ||
110 | |||
111 | // Test saving a particular path | ||
112 | mre.Reset(); | ||
113 | archiverModule.ArchiveInventory( | ||
114 | Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); | ||
115 | mre.WaitOne(60000, false); | ||
116 | |||
117 | byte[] archive = archiveWriteStream.ToArray(); | ||
118 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
119 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
120 | |||
121 | //bool gotControlFile = false; | ||
122 | bool gotObject1File = false; | ||
123 | //bool gotObject2File = false; | ||
124 | string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1); | ||
125 | string expectedObject1FilePath = string.Format( | ||
126 | "{0}{1}{2}", | ||
127 | ArchiveConstants.INVENTORY_PATH, | ||
128 | InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder), | ||
129 | expectedObject1FileName); | ||
130 | |||
131 | string filePath; | ||
132 | TarArchiveReader.TarEntryType tarEntryType; | ||
133 | |||
134 | // Console.WriteLine("Reading archive"); | ||
135 | |||
136 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
137 | { | ||
138 | // Console.WriteLine("Got {0}", filePath); | ||
139 | |||
140 | // if (ArchiveConstants.CONTROL_FILE_PATH == filePath) | ||
141 | // { | ||
142 | // gotControlFile = true; | ||
143 | // } | ||
144 | |||
145 | if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml")) | ||
146 | { | ||
147 | // string fileName = filePath.Remove(0, "Objects/".Length); | ||
148 | // | ||
149 | // if (fileName.StartsWith(part1.Name)) | ||
150 | // { | ||
151 | Assert.That(expectedObject1FilePath, Is.EqualTo(filePath)); | ||
152 | gotObject1File = true; | ||
153 | // } | ||
154 | // else if (fileName.StartsWith(part2.Name)) | ||
155 | // { | ||
156 | // Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); | ||
157 | // gotObject2File = true; | ||
158 | // } | ||
159 | } | ||
160 | } | ||
161 | |||
162 | // Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
163 | Assert.That(gotObject1File, Is.True, "No item1 file in archive"); | ||
164 | // Assert.That(gotObject2File, Is.True, "No object2 file in archive"); | ||
165 | |||
166 | // TODO: Test presence of more files and contents of files. | ||
167 | } | ||
168 | |||
169 | /// <summary> | ||
170 | /// Test loading an IAR to various different inventory paths. | 54 | /// Test loading an IAR to various different inventory paths. |
171 | /// </summary> | 55 | /// </summary> |
172 | [Test] | 56 | [Test] |
@@ -193,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
193 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); | 77 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); |
194 | 78 | ||
195 | // Now try loading to a root child folder | 79 | // Now try loading to a root child folder |
196 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); | 80 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); |
197 | MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); | 81 | MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); |
198 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); | 82 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); |
199 | 83 | ||
@@ -202,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
202 | Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); | 86 | Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); |
203 | 87 | ||
204 | // Now try loading to a more deeply nested folder | 88 | // Now try loading to a more deeply nested folder |
205 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); | 89 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); |
206 | archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); | 90 | archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); |
207 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); | 91 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); |
208 | 92 | ||
@@ -287,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
287 | item1.AssetID = asset1.FullID; | 171 | item1.AssetID = asset1.FullID; |
288 | item1.ID = item1Id; | 172 | item1.ID = item1Id; |
289 | InventoryFolderBase objsFolder | 173 | InventoryFolderBase objsFolder |
290 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; | 174 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; |
291 | item1.Folder = objsFolder.ID; | 175 | item1.Folder = objsFolder.ID; |
292 | scene.AddInventoryItem(item1); | 176 | scene.AddInventoryItem(item1); |
293 | 177 | ||
@@ -351,12 +235,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
351 | foldersCreated, nodesLoaded); | 235 | foldersCreated, nodesLoaded); |
352 | 236 | ||
353 | List<InventoryFolderBase> folder1Candidates | 237 | List<InventoryFolderBase> folder1Candidates |
354 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); | 238 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); |
355 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); | 239 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); |
356 | 240 | ||
357 | InventoryFolderBase folder1 = folder1Candidates[0]; | 241 | InventoryFolderBase folder1 = folder1Candidates[0]; |
358 | List<InventoryFolderBase> folder2aCandidates | 242 | List<InventoryFolderBase> folder2aCandidates |
359 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); | 243 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); |
360 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); | 244 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); |
361 | } | 245 | } |
362 | 246 | ||
@@ -368,17 +252,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
368 | foldersCreated, nodesLoaded); | 252 | foldersCreated, nodesLoaded); |
369 | 253 | ||
370 | List<InventoryFolderBase> folder1Candidates | 254 | List<InventoryFolderBase> folder1Candidates |
371 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); | 255 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); |
372 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); | 256 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); |
373 | 257 | ||
374 | InventoryFolderBase folder1 = folder1Candidates[0]; | 258 | InventoryFolderBase folder1 = folder1Candidates[0]; |
375 | 259 | ||
376 | List<InventoryFolderBase> folder2aCandidates | 260 | List<InventoryFolderBase> folder2aCandidates |
377 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); | 261 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); |
378 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); | 262 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); |
379 | 263 | ||
380 | List<InventoryFolderBase> folder2bCandidates | 264 | List<InventoryFolderBase> folder2bCandidates |
381 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName); | 265 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName); |
382 | Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); | 266 | Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); |
383 | } | 267 | } |
384 | } | 268 | } |
@@ -401,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
401 | 285 | ||
402 | InventoryFolderBase folder1 | 286 | InventoryFolderBase folder1 |
403 | = UserInventoryHelpers.CreateInventoryFolder( | 287 | = UserInventoryHelpers.CreateInventoryFolder( |
404 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 288 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); |
405 | 289 | ||
406 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); | 290 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); |
407 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 291 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
@@ -414,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
414 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 298 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
415 | 299 | ||
416 | List<InventoryFolderBase> folder1PostCandidates | 300 | List<InventoryFolderBase> folder1PostCandidates |
417 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 301 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); |
418 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); | 302 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); |
419 | 303 | ||
420 | // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. | 304 | // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. |
@@ -430,7 +314,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
430 | // Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); | 314 | // Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); |
431 | 315 | ||
432 | List<InventoryFolderBase> folder2PostCandidates | 316 | List<InventoryFolderBase> folder2PostCandidates |
433 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); | 317 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b"); |
434 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | 318 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); |
435 | } | 319 | } |
436 | 320 | ||
@@ -452,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
452 | 336 | ||
453 | InventoryFolderBase folder1 | 337 | InventoryFolderBase folder1 |
454 | = UserInventoryHelpers.CreateInventoryFolder( | 338 | = UserInventoryHelpers.CreateInventoryFolder( |
455 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 339 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); |
456 | 340 | ||
457 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); | 341 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); |
458 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 342 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
@@ -465,13 +349,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
465 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 349 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
466 | 350 | ||
467 | List<InventoryFolderBase> folder1PostCandidates | 351 | List<InventoryFolderBase> folder1PostCandidates |
468 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 352 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); |
469 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); | 353 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); |
470 | Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); | 354 | Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); |
471 | 355 | ||
472 | List<InventoryFolderBase> folder2PostCandidates | 356 | List<InventoryFolderBase> folder2PostCandidates |
473 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b"); | 357 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b"); |
474 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | 358 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); |
475 | } | 359 | } |
476 | } | 360 | } |
477 | } \ No newline at end of file | 361 | } |
362 | |||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs new file mode 100644 index 0000000..1b521fc --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs | |||
@@ -0,0 +1,194 @@ | |||
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.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using NUnit.Framework; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Data; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Serialization; | ||
38 | using OpenSim.Framework.Serialization.External; | ||
39 | using OpenSim.Framework.Communications; | ||
40 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | ||
41 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
44 | using OpenSim.Services.Interfaces; | ||
45 | using OpenSim.Tests.Common; | ||
46 | using OpenSim.Tests.Common.Mock; | ||
47 | |||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | ||
49 | { | ||
50 | [TestFixture] | ||
51 | public class InventoryArchiveLoadTests : InventoryArchiveTestCase | ||
52 | { | ||
53 | protected TestScene m_scene; | ||
54 | protected InventoryArchiverModule m_archiverModule; | ||
55 | |||
56 | [SetUp] | ||
57 | public override void SetUp() | ||
58 | { | ||
59 | base.SetUp(); | ||
60 | |||
61 | SerialiserModule serialiserModule = new SerialiserModule(); | ||
62 | m_archiverModule = new InventoryArchiverModule(); | ||
63 | |||
64 | m_scene = new SceneHelpers().SetupScene(); | ||
65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | ||
66 | } | ||
67 | |||
68 | [Test] | ||
69 | public void TestLoadCoalesecedItem() | ||
70 | { | ||
71 | TestHelpers.InMethod(); | ||
72 | // TestHelpers.EnableLogging(); | ||
73 | |||
74 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); | ||
75 | m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); | ||
76 | |||
77 | InventoryItemBase coaItem | ||
78 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); | ||
79 | |||
80 | Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); | ||
81 | |||
82 | string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); | ||
83 | |||
84 | CoalescedSceneObjects coa; | ||
85 | bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); | ||
86 | |||
87 | Assert.That(readResult, Is.True); | ||
88 | Assert.That(coa.Count, Is.EqualTo(2)); | ||
89 | |||
90 | List<SceneObjectGroup> coaObjects = coa.Objects; | ||
91 | Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); | ||
92 | Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); | ||
93 | |||
94 | Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); | ||
95 | Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); | ||
96 | } | ||
97 | |||
98 | /// <summary> | ||
99 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized | ||
100 | /// objects. | ||
101 | /// </summary> | ||
102 | [Test] | ||
103 | public void TestLoadIarCreatorAccountPresent() | ||
104 | { | ||
105 | TestHelpers.InMethod(); | ||
106 | // log4net.Config.XmlConfigurator.Configure(); | ||
107 | |||
108 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); | ||
109 | |||
110 | m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); | ||
111 | InventoryItemBase foundItem1 | ||
112 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); | ||
113 | |||
114 | Assert.That( | ||
115 | foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), | ||
116 | "Loaded item non-uuid creator doesn't match original"); | ||
117 | Assert.That( | ||
118 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), | ||
119 | "Loaded item uuid creator doesn't match original"); | ||
120 | Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), | ||
121 | "Loaded item owner doesn't match inventory reciever"); | ||
122 | |||
123 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
124 | string xmlData = Utils.BytesToString(asset1.Data); | ||
125 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
126 | |||
127 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); | ||
128 | } | ||
129 | |||
130 | // /// <summary> | ||
131 | // /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
132 | // /// an account exists with the same name as the creator, though not the same id. | ||
133 | // /// </summary> | ||
134 | // [Test] | ||
135 | // public void TestLoadIarV0_1SameNameCreator() | ||
136 | // { | ||
137 | // TestHelpers.InMethod(); | ||
138 | // TestHelpers.EnableLogging(); | ||
139 | // | ||
140 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); | ||
141 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); | ||
142 | // | ||
143 | // m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); | ||
144 | // InventoryItemBase foundItem1 | ||
145 | // = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
146 | // | ||
147 | // Assert.That( | ||
148 | // foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), | ||
149 | // "Loaded item non-uuid creator doesn't match original"); | ||
150 | // Assert.That( | ||
151 | // foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), | ||
152 | // "Loaded item uuid creator doesn't match original"); | ||
153 | // Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), | ||
154 | // "Loaded item owner doesn't match inventory reciever"); | ||
155 | // | ||
156 | // AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
157 | // string xmlData = Utils.BytesToString(asset1.Data); | ||
158 | // SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
159 | // | ||
160 | // Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); | ||
161 | // } | ||
162 | |||
163 | /// <summary> | ||
164 | /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
165 | /// the creator or an account with the creator's name does not exist within the system. | ||
166 | /// </summary> | ||
167 | [Test] | ||
168 | public void TestLoadIarV0_1AbsentCreator() | ||
169 | { | ||
170 | TestHelpers.InMethod(); | ||
171 | // log4net.Config.XmlConfigurator.Configure(); | ||
172 | |||
173 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); | ||
174 | m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); | ||
175 | |||
176 | InventoryItemBase foundItem1 | ||
177 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
178 | |||
179 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); | ||
180 | Assert.That( | ||
181 | foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), | ||
182 | "Loaded item non-uuid creator doesn't match that of the loading user"); | ||
183 | Assert.That( | ||
184 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), | ||
185 | "Loaded item uuid creator doesn't match that of the loading user"); | ||
186 | |||
187 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
188 | string xmlData = Utils.BytesToString(asset1.Data); | ||
189 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
190 | |||
191 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); | ||
192 | } | ||
193 | } | ||
194 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs index 06f6e49..5e7e24c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.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 InventoryArchiverTests : InventoryArchiveTestCase | 51 | public class InventoryArchiveSaveTests : InventoryArchiveTestCase |
52 | { | 52 | { |
53 | protected TestScene m_scene; | 53 | protected TestScene m_scene; |
54 | protected InventoryArchiverModule m_archiverModule; | 54 | protected InventoryArchiverModule m_archiverModule; |
@@ -64,36 +64,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
64 | m_scene = new 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 | |||
68 | [Test] | ||
69 | public void TestLoadCoalesecedItem() | ||
70 | { | ||
71 | TestHelpers.InMethod(); | ||
72 | // TestHelpers.EnableLogging(); | ||
73 | |||
74 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); | ||
75 | m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); | ||
76 | |||
77 | InventoryItemBase coaItem | ||
78 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); | ||
79 | |||
80 | Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); | ||
81 | |||
82 | string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); | ||
83 | |||
84 | CoalescedSceneObjects coa; | ||
85 | bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); | ||
86 | |||
87 | Assert.That(readResult, Is.True); | ||
88 | Assert.That(coa.Count, Is.EqualTo(2)); | ||
89 | |||
90 | List<SceneObjectGroup> coaObjects = coa.Objects; | ||
91 | Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); | ||
92 | Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); | ||
93 | |||
94 | Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); | ||
95 | Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); | ||
96 | } | ||
97 | 67 | ||
98 | /// <summary> | 68 | /// <summary> |
99 | /// Test that the IAR has the required files in the right order. | 69 | /// Test that the IAR has the required files in the right order. |
@@ -121,6 +91,139 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
121 | 91 | ||
122 | Assert.That(iarr.ControlFileLoaded, Is.True); | 92 | Assert.That(iarr.ControlFileLoaded, Is.True); |
123 | } | 93 | } |
94 | |||
95 | [Test] | ||
96 | public void TestSaveRootFolderToIar() | ||
97 | { | ||
98 | TestHelpers.InMethod(); | ||
99 | // TestHelpers.EnableLogging(); | ||
100 | |||
101 | string userFirstName = "Jock"; | ||
102 | string userLastName = "Stirrup"; | ||
103 | string userPassword = "troll"; | ||
104 | UUID userId = TestHelpers.ParseTail(0x20); | ||
105 | |||
106 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
107 | |||
108 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
109 | m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; | ||
110 | |||
111 | mre.Reset(); | ||
112 | m_archiverModule.ArchiveInventory( | ||
113 | Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); | ||
114 | mre.WaitOne(60000, false); | ||
115 | |||
116 | // Test created iar | ||
117 | byte[] archive = archiveWriteStream.ToArray(); | ||
118 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
119 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
120 | |||
121 | // InventoryArchiveUtils. | ||
122 | bool gotObjectsFolder = false; | ||
123 | |||
124 | string objectsFolderName | ||
125 | = string.Format( | ||
126 | "{0}{1}", | ||
127 | ArchiveConstants.INVENTORY_PATH, | ||
128 | InventoryArchiveWriteRequest.CreateArchiveFolderName( | ||
129 | UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects"))); | ||
130 | |||
131 | string filePath; | ||
132 | TarArchiveReader.TarEntryType tarEntryType; | ||
133 | |||
134 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
135 | { | ||
136 | // Console.WriteLine("Got {0}", filePath); | ||
137 | |||
138 | // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory() | ||
139 | // XXX: But really we need to stop all that stuff being created in tests or check for such folders | ||
140 | // more thoroughly | ||
141 | if (filePath == objectsFolderName) | ||
142 | gotObjectsFolder = true; | ||
143 | } | ||
144 | |||
145 | Assert.That(gotObjectsFolder, Is.True); | ||
146 | } | ||
147 | |||
148 | [Test] | ||
149 | public void TestSaveNonRootFolderToIar() | ||
150 | { | ||
151 | TestHelpers.InMethod(); | ||
152 | // TestHelpers.EnableLogging(); | ||
153 | |||
154 | string userFirstName = "Jock"; | ||
155 | string userLastName = "Stirrup"; | ||
156 | string userPassword = "troll"; | ||
157 | UUID userId = TestHelpers.ParseTail(0x20); | ||
158 | |||
159 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
160 | |||
161 | // Create base folder | ||
162 | InventoryFolderBase f1 | ||
163 | = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true); | ||
164 | |||
165 | // Create item1 | ||
166 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5); | ||
167 | InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1"); | ||
168 | |||
169 | // Create embedded folder | ||
170 | InventoryFolderBase f1_1 | ||
171 | = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true); | ||
172 | |||
173 | // Create embedded item | ||
174 | SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6); | ||
175 | InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1"); | ||
176 | |||
177 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
178 | m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; | ||
179 | |||
180 | mre.Reset(); | ||
181 | m_archiverModule.ArchiveInventory( | ||
182 | Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); | ||
183 | mre.WaitOne(60000, false); | ||
184 | |||
185 | // Test created iar | ||
186 | byte[] archive = archiveWriteStream.ToArray(); | ||
187 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
188 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
189 | |||
190 | // InventoryArchiveUtils. | ||
191 | bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false; | ||
192 | |||
193 | string f1FileName | ||
194 | = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1)); | ||
195 | string f1_1FileName | ||
196 | = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1)); | ||
197 | string so1FileName | ||
198 | = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1)); | ||
199 | string so2FileName | ||
200 | = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2)); | ||
201 | |||
202 | string filePath; | ||
203 | TarArchiveReader.TarEntryType tarEntryType; | ||
204 | |||
205 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
206 | { | ||
207 | // Console.WriteLine("Got {0}", filePath); | ||
208 | |||
209 | if (filePath == f1FileName) | ||
210 | gotf1 = true; | ||
211 | else if (filePath == f1_1FileName) | ||
212 | gotf1_1 = true; | ||
213 | else if (filePath == so1FileName) | ||
214 | gotso1 = true; | ||
215 | else if (filePath == so2FileName) | ||
216 | gotso2 = true; | ||
217 | } | ||
218 | |||
219 | // Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
220 | Assert.That(gotf1, Is.True); | ||
221 | Assert.That(gotf1_1, Is.True); | ||
222 | Assert.That(gotso1, Is.True); | ||
223 | Assert.That(gotso2, Is.True); | ||
224 | |||
225 | // TODO: Test presence of more files and contents of files. | ||
226 | } | ||
124 | 227 | ||
125 | /// <summary> | 228 | /// <summary> |
126 | /// Test saving a single inventory item to an IAR | 229 | /// Test saving a single inventory item to an IAR |
@@ -155,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
155 | item1.AssetID = asset1.FullID; | 258 | item1.AssetID = asset1.FullID; |
156 | item1.ID = item1Id; | 259 | item1.ID = item1Id; |
157 | InventoryFolderBase objsFolder | 260 | InventoryFolderBase objsFolder |
158 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | 261 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; |
159 | item1.Folder = objsFolder.ID; | 262 | item1.Folder = objsFolder.ID; |
160 | m_scene.AddInventoryItem(item1); | 263 | m_scene.AddInventoryItem(item1); |
161 | 264 | ||
@@ -250,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
250 | item1.AssetID = asset1.FullID; | 353 | item1.AssetID = asset1.FullID; |
251 | item1.ID = item1Id; | 354 | item1.ID = item1Id; |
252 | InventoryFolderBase objsFolder | 355 | InventoryFolderBase objsFolder |
253 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | 356 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; |
254 | item1.Folder = objsFolder.ID; | 357 | item1.Folder = objsFolder.ID; |
255 | m_scene.AddInventoryItem(item1); | 358 | m_scene.AddInventoryItem(item1); |
256 | 359 | ||
@@ -317,101 +420,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
317 | 420 | ||
318 | // TODO: Test presence of more files and contents of files. | 421 | // TODO: Test presence of more files and contents of files. |
319 | } | 422 | } |
320 | |||
321 | /// <summary> | ||
322 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized | ||
323 | /// objects. | ||
324 | /// </summary> | ||
325 | [Test] | ||
326 | public void TestLoadIarCreatorAccountPresent() | ||
327 | { | ||
328 | TestHelpers.InMethod(); | ||
329 | // log4net.Config.XmlConfigurator.Configure(); | ||
330 | |||
331 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); | ||
332 | |||
333 | m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); | ||
334 | InventoryItemBase foundItem1 | ||
335 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); | ||
336 | |||
337 | Assert.That( | ||
338 | foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), | ||
339 | "Loaded item non-uuid creator doesn't match original"); | ||
340 | Assert.That( | ||
341 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), | ||
342 | "Loaded item uuid creator doesn't match original"); | ||
343 | Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), | ||
344 | "Loaded item owner doesn't match inventory reciever"); | ||
345 | |||
346 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
347 | string xmlData = Utils.BytesToString(asset1.Data); | ||
348 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
349 | |||
350 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); | ||
351 | } | ||
352 | |||
353 | // /// <summary> | ||
354 | // /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
355 | // /// an account exists with the same name as the creator, though not the same id. | ||
356 | // /// </summary> | ||
357 | // [Test] | ||
358 | // public void TestLoadIarV0_1SameNameCreator() | ||
359 | // { | ||
360 | // TestHelpers.InMethod(); | ||
361 | // TestHelpers.EnableLogging(); | ||
362 | // | ||
363 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); | ||
364 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); | ||
365 | // | ||
366 | // m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); | ||
367 | // InventoryItemBase foundItem1 | ||
368 | // = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
369 | // | ||
370 | // Assert.That( | ||
371 | // foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), | ||
372 | // "Loaded item non-uuid creator doesn't match original"); | ||
373 | // Assert.That( | ||
374 | // foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), | ||
375 | // "Loaded item uuid creator doesn't match original"); | ||
376 | // Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), | ||
377 | // "Loaded item owner doesn't match inventory reciever"); | ||
378 | // | ||
379 | // AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
380 | // string xmlData = Utils.BytesToString(asset1.Data); | ||
381 | // SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
382 | // | ||
383 | // Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); | ||
384 | // } | ||
385 | |||
386 | /// <summary> | ||
387 | /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
388 | /// the creator or an account with the creator's name does not exist within the system. | ||
389 | /// </summary> | ||
390 | [Test] | ||
391 | public void TestLoadIarV0_1AbsentCreator() | ||
392 | { | ||
393 | TestHelpers.InMethod(); | ||
394 | // log4net.Config.XmlConfigurator.Configure(); | ||
395 | |||
396 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); | ||
397 | m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); | ||
398 | |||
399 | InventoryItemBase foundItem1 | ||
400 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
401 | |||
402 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); | ||
403 | Assert.That( | ||
404 | foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), | ||
405 | "Loaded item non-uuid creator doesn't match that of the loading user"); | ||
406 | Assert.That( | ||
407 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), | ||
408 | "Loaded item uuid creator doesn't match that of the loading user"); | ||
409 | |||
410 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
411 | string xmlData = Utils.BytesToString(asset1.Data); | ||
412 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
413 | |||
414 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); | ||
415 | } | ||
416 | } | 423 | } |
417 | } \ No newline at end of file | 424 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 4cfa33d..ae58dfd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -316,76 +316,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
316 | } | 316 | } |
317 | } | 317 | } |
318 | 318 | ||
319 | // Disabled for now as it looks like http://opensimulator.org/mantis/view.php?id=6311 was fixed by fixes | 319 | // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name> |
320 | // to inventory folder versioning allowing the viewer to move the received folder itself as happens on the | 320 | // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be |
321 | // LL grid. Doing it again server-side then wrongly does a second create and move | 321 | // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet |
322 | // // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~<name> | 322 | // happening, possibly because we are not sending the correct inventory update messages with the correct |
323 | // // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis | 323 | // transaction IDs |
324 | // // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously | 324 | else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) |
325 | // // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. | 325 | { |
326 | // else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) | 326 | UUID destinationFolderID = UUID.Zero; |
327 | // { | 327 | |
328 | // UUID destinationFolderID = UUID.Zero; | 328 | if (im.binaryBucket != null && im.binaryBucket.Length >= 16) |
329 | // | 329 | { |
330 | // if (im.binaryBucket != null && im.binaryBucket.Length >= 16) | 330 | destinationFolderID = new UUID(im.binaryBucket, 0); |
331 | // { | 331 | } |
332 | // destinationFolderID = new UUID(im.binaryBucket, 0); | 332 | |
333 | // } | 333 | if (destinationFolderID != UUID.Zero) |
334 | // | 334 | { |
335 | // if (destinationFolderID != UUID.Zero) | 335 | InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); |
336 | // { | 336 | if (destinationFolder == null) |
337 | // InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); | 337 | { |
338 | // if (destinationFolder == null) | 338 | m_log.WarnFormat( |
339 | // { | 339 | "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", |
340 | // m_log.WarnFormat( | 340 | client.Name, scene.Name, destinationFolderID); |
341 | // "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", | 341 | |
342 | // client.Name, scene.Name, destinationFolderID); | 342 | return; |
343 | // | 343 | } |
344 | // return; | 344 | |
345 | // } | 345 | IInventoryService invService = scene.InventoryService; |
346 | // | 346 | |
347 | // IInventoryService invService = scene.InventoryService; | 347 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip |
348 | // | 348 | |
349 | // UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip | 349 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); |
350 | // | 350 | item = invService.GetItem(item); |
351 | // InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); | 351 | InventoryFolderBase folder = null; |
352 | // item = invService.GetItem(item); | 352 | UUID? previousParentFolderID = null; |
353 | // InventoryFolderBase folder = null; | 353 | |
354 | // UUID? previousParentFolderID = null; | 354 | if (item != null) // It's an item |
355 | // | 355 | { |
356 | // if (item != null) // It's an item | 356 | previousParentFolderID = item.Folder; |
357 | // { | 357 | item.Folder = destinationFolderID; |
358 | // previousParentFolderID = item.Folder; | 358 | |
359 | // item.Folder = destinationFolderID; | 359 | invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); |
360 | // | 360 | scene.AddInventoryItem(client, item); |
361 | // invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); | 361 | } |
362 | // scene.AddInventoryItem(client, item); | 362 | else |
363 | // } | 363 | { |
364 | // else | 364 | folder = new InventoryFolderBase(inventoryID, client.AgentId); |
365 | // { | 365 | folder = invService.GetFolder(folder); |
366 | // folder = new InventoryFolderBase(inventoryID, client.AgentId); | 366 | |
367 | // folder = invService.GetFolder(folder); | 367 | if (folder != null) // It's a folder |
368 | // | 368 | { |
369 | // if (folder != null) // It's a folder | 369 | previousParentFolderID = folder.ParentID; |
370 | // { | 370 | folder.ParentID = destinationFolderID; |
371 | // previousParentFolderID = folder.ParentID; | 371 | invService.MoveFolder(folder); |
372 | // folder.ParentID = destinationFolderID; | 372 | } |
373 | // invService.MoveFolder(folder); | 373 | } |
374 | // } | 374 | |
375 | // } | 375 | // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). |
376 | // | 376 | if (previousParentFolderID != null) |
377 | // // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). | 377 | { |
378 | // if (previousParentFolderID != null) | 378 | InventoryFolderBase previousParentFolder |
379 | // { | 379 | = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); |
380 | // InventoryFolderBase previousParentFolder | 380 | previousParentFolder = invService.GetFolder(previousParentFolder); |
381 | // = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); | 381 | scene.SendInventoryUpdate(client, previousParentFolder, true, true); |
382 | // previousParentFolder = invService.GetFolder(previousParentFolder); | 382 | |
383 | // scene.SendInventoryUpdate(client, previousParentFolder, true, true); | 383 | scene.SendInventoryUpdate(client, destinationFolder, true, true); |
384 | // | 384 | } |
385 | // scene.SendInventoryUpdate(client, destinationFolder, true, true); | 385 | } |
386 | // } | 386 | } |
387 | // } | ||
388 | // } | ||
389 | else if ( | 387 | else if ( |
390 | im.dialog == (byte)InstantMessageDialog.InventoryDeclined | 388 | im.dialog == (byte)InstantMessageDialog.InventoryDeclined |
391 | || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) | 389 | || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 232a4fe..a34f2d2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -65,7 +65,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
65 | { | 65 | { |
66 | m_Enabled = true; | 66 | m_Enabled = true; |
67 | 67 | ||
68 | m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty); | 68 | m_ThisGridURL = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI", |
69 | new string[] { "Startup", "Hypergrid", "Messaging" }, String.Empty); | ||
70 | // Legacy. Remove soon! | ||
71 | m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", m_ThisGridURL); | ||
69 | m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); | 72 | m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); |
70 | } | 73 | } |
71 | } | 74 | } |
@@ -151,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
151 | 154 | ||
152 | void OnIncomingInstantMessage(GridInstantMessage im) | 155 | void OnIncomingInstantMessage(GridInstantMessage im) |
153 | { | 156 | { |
154 | if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) | 157 | if (im.dialog == (byte)InstantMessageDialog.RequestTeleport |
158 | || im.dialog == (byte)InstantMessageDialog.GodLikeRequestTeleport) | ||
155 | { | 159 | { |
156 | UUID sessionID = new UUID(im.imSessionID); | 160 | UUID sessionID = new UUID(im.imSessionID); |
157 | 161 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index f3adb95..0c64f19 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
165 | (uint)presence.AbsolutePosition.Y, | 165 | (uint)presence.AbsolutePosition.Y, |
166 | (uint)presence.AbsolutePosition.Z + 2); | 166 | (uint)presence.AbsolutePosition.Z + 2); |
167 | 167 | ||
168 | m_log.DebugFormat("[LURE]: TP invite with message {0}", message); | 168 | m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); |
169 | 169 | ||
170 | GridInstantMessage m; | 170 | GridInstantMessage m; |
171 | 171 | ||