diff options
Diffstat (limited to '')
10 files changed, 1219 insertions, 516 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index ecbd07f..4a06fd1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -61,16 +61,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
61 | 61 | ||
62 | private UserAccount m_userInfo; | 62 | private UserAccount m_userInfo; |
63 | private string m_invPath; | 63 | private string m_invPath; |
64 | |||
65 | /// <value> | ||
66 | /// ID of this request | ||
67 | /// </value> | ||
68 | protected UUID m_id; | ||
64 | 69 | ||
65 | /// <summary> | 70 | /// <summary> |
66 | /// Do we want to merge this load with existing inventory? | 71 | /// Do we want to merge this load with existing inventory? |
67 | /// </summary> | 72 | /// </summary> |
68 | protected bool m_merge; | 73 | protected bool m_merge; |
69 | 74 | ||
70 | /// <value> | 75 | protected IInventoryService m_InventoryService; |
71 | /// We only use this to request modules | 76 | protected IAssetService m_AssetService; |
72 | /// </value> | 77 | protected IUserAccountService m_UserAccountService; |
73 | protected Scene m_scene; | 78 | |
79 | private InventoryArchiverModule m_module; | ||
74 | 80 | ||
75 | /// <value> | 81 | /// <value> |
76 | /// The stream from which the inventory archive will be loaded. | 82 | /// The stream from which the inventory archive will be loaded. |
@@ -115,12 +121,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
115 | /// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids | 121 | /// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids |
116 | /// after OSP resolution (since OSP creators are only stored in the item | 122 | /// after OSP resolution (since OSP creators are only stored in the item |
117 | /// </summary> | 123 | /// </summary> |
118 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); | 124 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); |
125 | |||
126 | public InventoryArchiveReadRequest( | ||
127 | IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) | ||
128 | : this(UUID.Zero, null, | ||
129 | inv, | ||
130 | assets, | ||
131 | uacc, | ||
132 | userInfo, | ||
133 | invPath, | ||
134 | loadPath, | ||
135 | merge) | ||
136 | { | ||
137 | } | ||
119 | 138 | ||
120 | public InventoryArchiveReadRequest( | 139 | public InventoryArchiveReadRequest( |
121 | Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) | 140 | UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) |
122 | : this( | 141 | : this( |
123 | scene, | 142 | id, |
143 | module, | ||
144 | inv, | ||
145 | assets, | ||
146 | uacc, | ||
124 | userInfo, | 147 | userInfo, |
125 | invPath, | 148 | invPath, |
126 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), | 149 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), |
@@ -129,13 +152,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
129 | } | 152 | } |
130 | 153 | ||
131 | public InventoryArchiveReadRequest( | 154 | public InventoryArchiveReadRequest( |
132 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) | 155 | UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge) |
133 | { | 156 | { |
134 | m_scene = scene; | 157 | m_id = id; |
158 | m_InventoryService = inv; | ||
159 | m_AssetService = assets; | ||
160 | m_UserAccountService = uacc; | ||
135 | m_merge = merge; | 161 | m_merge = merge; |
136 | m_userInfo = userInfo; | 162 | m_userInfo = userInfo; |
137 | m_invPath = invPath; | 163 | m_invPath = invPath; |
138 | m_loadStream = loadStream; | 164 | m_loadStream = loadStream; |
165 | m_module = module; | ||
139 | 166 | ||
140 | // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things | 167 | // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things |
141 | // (I thought they weren't). We will need to bump the version number and perform this check on all | 168 | // (I thought they weren't). We will need to bump the version number and perform this check on all |
@@ -158,11 +185,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
158 | { | 185 | { |
159 | try | 186 | try |
160 | { | 187 | { |
188 | Exception reportedException = null; | ||
189 | |||
161 | string filePath = "ERROR"; | 190 | string filePath = "ERROR"; |
162 | 191 | ||
163 | List<InventoryFolderBase> folderCandidates | 192 | List<InventoryFolderBase> folderCandidates |
164 | = InventoryArchiveUtils.FindFolderByPath( | 193 | = InventoryArchiveUtils.FindFoldersByPath( |
165 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); | 194 | m_InventoryService, m_userInfo.PrincipalID, m_invPath); |
166 | 195 | ||
167 | if (folderCandidates.Count == 0) | 196 | if (folderCandidates.Count == 0) |
168 | { | 197 | { |
@@ -194,14 +223,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
194 | } | 223 | } |
195 | 224 | ||
196 | archive.Close(); | 225 | archive.Close(); |
197 | 226 | ||
198 | m_log.DebugFormat( | 227 | m_log.DebugFormat( |
199 | "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", | 228 | "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", |
200 | m_successfulAssetRestores, m_failedAssetRestores); | 229 | m_successfulAssetRestores, m_failedAssetRestores); |
201 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores); | 230 | |
231 | //Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required | ||
232 | if(m_module != null) | ||
233 | m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores); | ||
202 | 234 | ||
203 | return m_loadedNodes; | 235 | return m_loadedNodes; |
204 | } | 236 | } |
237 | catch(Exception Ex) | ||
238 | { | ||
239 | // Trigger saved event with failed result and exception data | ||
240 | if (m_module != null) | ||
241 | m_module.TriggerInventoryArchiveLoaded(m_id, false, m_userInfo, m_invPath, m_loadStream, Ex, 0); | ||
242 | |||
243 | return m_loadedNodes; | ||
244 | } | ||
205 | finally | 245 | finally |
206 | { | 246 | { |
207 | m_loadStream.Close(); | 247 | m_loadStream.Close(); |
@@ -296,8 +336,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
296 | // iar name and try to find that instead. | 336 | // iar name and try to find that instead. |
297 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | 337 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); |
298 | List<InventoryFolderBase> folderCandidates | 338 | List<InventoryFolderBase> folderCandidates |
299 | = InventoryArchiveUtils.FindFolderByPath( | 339 | = InventoryArchiveUtils.FindFoldersByPath( |
300 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); | 340 | m_InventoryService, m_userInfo.PrincipalID, plainPath); |
301 | 341 | ||
302 | if (folderCandidates.Count != 0) | 342 | if (folderCandidates.Count != 0) |
303 | { | 343 | { |
@@ -372,15 +412,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
372 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); | 412 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); |
373 | UUID newFolderId = UUID.Random(); | 413 | UUID newFolderId = UUID.Random(); |
374 | 414 | ||
375 | // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be | ||
376 | // deleted once the client has relogged. | ||
377 | // The root folder appears to be labelled AssetType.Folder (shows up as "Category" in the client) | ||
378 | // even though there is a AssetType.RootCategory | ||
379 | destFolder | 415 | destFolder |
380 | = new InventoryFolderBase( | 416 | = new InventoryFolderBase( |
381 | newFolderId, newFolderName, m_userInfo.PrincipalID, | 417 | newFolderId, newFolderName, m_userInfo.PrincipalID, |
382 | (short)AssetType.Unknown, destFolder.ID, 1); | 418 | (short)FolderType.None, destFolder.ID, 1); |
383 | m_scene.InventoryService.AddFolder(destFolder); | 419 | m_InventoryService.AddFolder(destFolder); |
384 | 420 | ||
385 | // Record that we have now created this folder | 421 | // Record that we have now created this folder |
386 | iarPathExisting += rawDirsToCreate[i] + "/"; | 422 | iarPathExisting += rawDirsToCreate[i] + "/"; |
@@ -406,7 +442,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | // Don't use the item ID that's in the file | 442 | // Don't use the item ID that's in the file |
407 | item.ID = UUID.Random(); | 443 | item.ID = UUID.Random(); |
408 | 444 | ||
409 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); | 445 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); |
410 | if (UUID.Zero != ospResolvedId) // The user exists in this grid | 446 | if (UUID.Zero != ospResolvedId) // The user exists in this grid |
411 | { | 447 | { |
412 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); | 448 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); |
@@ -418,7 +454,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
418 | item.CreatorId = ospResolvedId.ToString(); | 454 | item.CreatorId = ospResolvedId.ToString(); |
419 | item.CreatorData = string.Empty; | 455 | item.CreatorData = string.Empty; |
420 | } | 456 | } |
421 | else if (item.CreatorData == null || item.CreatorData == String.Empty) | 457 | else if (string.IsNullOrEmpty(item.CreatorData)) |
422 | { | 458 | { |
423 | item.CreatorId = m_userInfo.PrincipalID.ToString(); | 459 | item.CreatorId = m_userInfo.PrincipalID.ToString(); |
424 | // item.CreatorIdAsUuid = new UUID(item.CreatorId); | 460 | // item.CreatorIdAsUuid = new UUID(item.CreatorId); |
@@ -436,7 +472,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
436 | // relying on native tar tools. | 472 | // relying on native tar tools. |
437 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; | 473 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; |
438 | 474 | ||
439 | m_scene.AddInventoryItem(item); | 475 | if (!m_InventoryService.AddItem(item)) |
476 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); | ||
440 | 477 | ||
441 | return item; | 478 | return item; |
442 | } | 479 | } |
@@ -479,52 +516,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
479 | { | 516 | { |
480 | if (m_creatorIdForAssetId.ContainsKey(assetId)) | 517 | if (m_creatorIdForAssetId.ContainsKey(assetId)) |
481 | { | 518 | { |
482 | string xmlData = Utils.BytesToString(data); | 519 | data = SceneObjectSerializer.ModifySerializedObject(assetId, data, |
483 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 520 | sog => { |
521 | bool modified = false; | ||
522 | |||
523 | foreach (SceneObjectPart sop in sog.Parts) | ||
524 | { | ||
525 | if (string.IsNullOrEmpty(sop.CreatorData)) | ||
526 | { | ||
527 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | ||
528 | modified = true; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | return modified; | ||
533 | }); | ||
484 | 534 | ||
485 | CoalescedSceneObjects coa = null; | 535 | if (data == null) |
486 | if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa)) | 536 | return false; |
487 | { | ||
488 | // m_log.DebugFormat( | ||
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 | } | ||
498 | |||
499 | sceneObjects.AddRange(coa.Objects); | ||
500 | } | ||
501 | else | ||
502 | { | ||
503 | SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
504 | |||
505 | if (deserializedObject != null) | ||
506 | { | ||
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 | } | ||
517 | } | ||
518 | |||
519 | foreach (SceneObjectGroup sog in sceneObjects) | ||
520 | foreach (SceneObjectPart sop in sog.Parts) | ||
521 | if (sop.CreatorData == null || sop.CreatorData == "") | ||
522 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | ||
523 | |||
524 | if (coa != null) | ||
525 | data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa)); | ||
526 | else | ||
527 | data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0])); | ||
528 | } | 537 | } |
529 | } | 538 | } |
530 | 539 | ||
@@ -533,7 +542,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
533 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); | 542 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); |
534 | asset.Data = data; | 543 | asset.Data = data; |
535 | 544 | ||
536 | m_scene.AssetService.Store(asset); | 545 | m_AssetService.Store(asset); |
537 | 546 | ||
538 | return true; | 547 | return true; |
539 | } | 548 | } |
@@ -546,7 +555,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
546 | return false; | 555 | return false; |
547 | } | 556 | } |
548 | } | 557 | } |
549 | 558 | ||
550 | /// <summary> | 559 | /// <summary> |
551 | /// Load control file | 560 | /// Load control file |
552 | /// </summary> | 561 | /// </summary> |
@@ -652,4 +661,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
652 | m_assetsLoaded = true; | 661 | m_assetsLoaded = true; |
653 | } | 662 | } |
654 | } | 663 | } |
655 | } \ No newline at end of file | 664 | } |
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..f002ad7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -34,6 +34,7 @@ using System.Xml; | |||
34 | using log4net; | 34 | using log4net; |
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Monitoring; | ||
37 | using OpenSim.Framework.Serialization; | 38 | using OpenSim.Framework.Serialization; |
38 | using OpenSim.Framework.Serialization.External; | 39 | using OpenSim.Framework.Serialization.External; |
39 | using OpenSim.Region.CoreModules.World.Archiver; | 40 | using OpenSim.Region.CoreModules.World.Archiver; |
@@ -42,6 +43,8 @@ using OpenSim.Services.Interfaces; | |||
42 | using Ionic.Zlib; | 43 | using Ionic.Zlib; |
43 | using GZipStream = Ionic.Zlib.GZipStream; | 44 | using GZipStream = Ionic.Zlib.GZipStream; |
44 | using CompressionMode = Ionic.Zlib.CompressionMode; | 45 | using CompressionMode = Ionic.Zlib.CompressionMode; |
46 | using CompressionLevel = Ionic.Zlib.CompressionLevel; | ||
47 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
45 | 48 | ||
46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | 49 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver |
47 | { | 50 | { |
@@ -54,6 +57,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
54 | /// </summary> | 57 | /// </summary> |
55 | public bool SaveAssets { get; set; } | 58 | public bool SaveAssets { get; set; } |
56 | 59 | ||
60 | /// <summary> | ||
61 | /// Determines which items will be included in the archive, according to their permissions. | ||
62 | /// Default is null, meaning no permission checks. | ||
63 | /// </summary> | ||
64 | public string FilterContent { get; set; } | ||
65 | |||
66 | /// <summary> | ||
67 | /// Counter for inventory items saved to archive for passing to compltion event | ||
68 | /// </summary> | ||
69 | public int CountItems { get; set; } | ||
70 | |||
71 | /// <summary> | ||
72 | /// Counter for inventory items skipped due to permission filter option for passing to compltion event | ||
73 | /// </summary> | ||
74 | public int CountFiltered { get; set; } | ||
75 | |||
57 | /// <value> | 76 | /// <value> |
58 | /// Used to select all inventory nodes in a folder but not the folder itself | 77 | /// Used to select all inventory nodes in a folder but not the folder itself |
59 | /// </value> | 78 | /// </value> |
@@ -73,12 +92,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
73 | /// <value> | 92 | /// <value> |
74 | /// ID of this request | 93 | /// ID of this request |
75 | /// </value> | 94 | /// </value> |
76 | protected Guid m_id; | 95 | protected UUID m_id; |
77 | |||
78 | /// <value> | ||
79 | /// Used to collect the uuids of the assets that we need to save into the archive | ||
80 | /// </value> | ||
81 | protected Dictionary<UUID, AssetType> m_assetUuids = new Dictionary<UUID, AssetType>(); | ||
82 | 96 | ||
83 | /// <value> | 97 | /// <value> |
84 | /// Used to collect the uuids of the users that we need to save into the archive | 98 | /// Used to collect the uuids of the users that we need to save into the archive |
@@ -94,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
94 | /// Constructor | 108 | /// Constructor |
95 | /// </summary> | 109 | /// </summary> |
96 | public InventoryArchiveWriteRequest( | 110 | public InventoryArchiveWriteRequest( |
97 | Guid id, InventoryArchiverModule module, Scene scene, | 111 | UUID id, InventoryArchiverModule module, Scene scene, |
98 | UserAccount userInfo, string invPath, string savePath) | 112 | UserAccount userInfo, string invPath, string savePath) |
99 | : this( | 113 | : this( |
100 | id, | 114 | id, |
@@ -110,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
110 | /// Constructor | 124 | /// Constructor |
111 | /// </summary> | 125 | /// </summary> |
112 | public InventoryArchiveWriteRequest( | 126 | public InventoryArchiveWriteRequest( |
113 | Guid id, InventoryArchiverModule module, Scene scene, | 127 | UUID id, InventoryArchiverModule module, Scene scene, |
114 | UserAccount userInfo, string invPath, Stream saveStream) | 128 | UserAccount userInfo, string invPath, Stream saveStream) |
115 | { | 129 | { |
116 | m_id = id; | 130 | m_id = id; |
@@ -122,9 +136,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
122 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); | 136 | m_assetGatherer = new UuidGatherer(m_scene.AssetService); |
123 | 137 | ||
124 | SaveAssets = true; | 138 | SaveAssets = true; |
139 | FilterContent = null; | ||
125 | } | 140 | } |
126 | 141 | ||
127 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) | 142 | protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut) |
128 | { | 143 | { |
129 | Exception reportedException = null; | 144 | Exception reportedException = null; |
130 | bool succeeded = true; | 145 | bool succeeded = true; |
@@ -143,8 +158,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
143 | m_saveStream.Close(); | 158 | m_saveStream.Close(); |
144 | } | 159 | } |
145 | 160 | ||
161 | if (timedOut) | ||
162 | { | ||
163 | succeeded = false; | ||
164 | reportedException = new Exception("Loading assets timed out"); | ||
165 | } | ||
166 | |||
146 | m_module.TriggerInventoryArchiveSaved( | 167 | m_module.TriggerInventoryArchiveSaved( |
147 | m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); | 168 | m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException, CountItems, CountFiltered); |
148 | } | 169 | } |
149 | 170 | ||
150 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) | 171 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) |
@@ -160,10 +181,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
160 | "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", | 181 | "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", |
161 | inventoryItem.Name, inventoryItem.ID, path); | 182 | inventoryItem.Name, inventoryItem.ID, path); |
162 | } | 183 | } |
184 | |||
185 | CountFiltered++; | ||
186 | |||
163 | return; | 187 | return; |
164 | } | 188 | } |
165 | } | 189 | } |
166 | 190 | ||
191 | // Check For Permissions Filter Flags | ||
192 | if (!CanUserArchiveObject(m_userInfo.PrincipalID, inventoryItem)) | ||
193 | { | ||
194 | m_log.InfoFormat( | ||
195 | "[INVENTORY ARCHIVER]: Insufficient permissions, skipping inventory item {0} {1} at {2}", | ||
196 | inventoryItem.Name, inventoryItem.ID, path); | ||
197 | |||
198 | // Count Items Excluded | ||
199 | CountFiltered++; | ||
200 | |||
201 | return; | ||
202 | } | ||
203 | |||
167 | if (options.ContainsKey("verbose")) | 204 | if (options.ContainsKey("verbose")) |
168 | m_log.InfoFormat( | 205 | m_log.InfoFormat( |
169 | "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})", | 206 | "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})", |
@@ -179,9 +216,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
179 | 216 | ||
180 | AssetType itemAssetType = (AssetType)inventoryItem.AssetType; | 217 | AssetType itemAssetType = (AssetType)inventoryItem.AssetType; |
181 | 218 | ||
219 | // Count inventory items (different to asset count) | ||
220 | CountItems++; | ||
221 | |||
182 | // Don't chase down link asset items as they actually point to their target item IDs rather than an asset | 222 | // Don't chase down link asset items as they actually point to their target item IDs rather than an asset |
183 | if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) | 223 | if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) |
184 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | 224 | m_assetGatherer.AddForInspection(inventoryItem.AssetID); |
185 | } | 225 | } |
186 | 226 | ||
187 | /// <summary> | 227 | /// <summary> |
@@ -237,6 +277,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
237 | } | 277 | } |
238 | 278 | ||
239 | /// <summary> | 279 | /// <summary> |
280 | /// Checks whether the user has permission to export an inventory item to an IAR. | ||
281 | /// </summary> | ||
282 | /// <param name="UserID">The user</param> | ||
283 | /// <param name="InvItem">The inventory item</param> | ||
284 | /// <returns>Whether the user is allowed to export the object to an IAR</returns> | ||
285 | private bool CanUserArchiveObject(UUID UserID, InventoryItemBase InvItem) | ||
286 | { | ||
287 | if (FilterContent == null) | ||
288 | return true;// Default To Allow Export | ||
289 | |||
290 | bool permitted = true; | ||
291 | |||
292 | bool canCopy = (InvItem.CurrentPermissions & (uint)PermissionMask.Copy) != 0; | ||
293 | bool canTransfer = (InvItem.CurrentPermissions & (uint)PermissionMask.Transfer) != 0; | ||
294 | bool canMod = (InvItem.CurrentPermissions & (uint)PermissionMask.Modify) != 0; | ||
295 | |||
296 | if (FilterContent.Contains("C") && !canCopy) | ||
297 | permitted = false; | ||
298 | |||
299 | if (FilterContent.Contains("T") && !canTransfer) | ||
300 | permitted = false; | ||
301 | |||
302 | if (FilterContent.Contains("M") && !canMod) | ||
303 | permitted = false; | ||
304 | |||
305 | return permitted; | ||
306 | } | ||
307 | |||
308 | /// <summary> | ||
240 | /// Execute the inventory write request | 309 | /// Execute the inventory write request |
241 | /// </summary> | 310 | /// </summary> |
242 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) | 311 | public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) |
@@ -244,6 +313,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
244 | if (options.ContainsKey("noassets") && (bool)options["noassets"]) | 313 | if (options.ContainsKey("noassets") && (bool)options["noassets"]) |
245 | SaveAssets = false; | 314 | SaveAssets = false; |
246 | 315 | ||
316 | // Set Permission filter if flag is set | ||
317 | if (options.ContainsKey("checkPermissions")) | ||
318 | { | ||
319 | Object temp; | ||
320 | if (options.TryGetValue("checkPermissions", out temp)) | ||
321 | FilterContent = temp.ToString().ToUpper(); | ||
322 | } | ||
323 | |||
247 | try | 324 | try |
248 | { | 325 | { |
249 | InventoryFolderBase inventoryFolder = null; | 326 | InventoryFolderBase inventoryFolder = null; |
@@ -266,6 +343,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
266 | saveFolderContentsOnly = true; | 343 | saveFolderContentsOnly = true; |
267 | maxComponentIndex--; | 344 | maxComponentIndex--; |
268 | } | 345 | } |
346 | else if (maxComponentIndex == -1) | ||
347 | { | ||
348 | // If the user has just specified "/", then don't save the root "My Inventory" folder. This is | ||
349 | // more intuitive then requiring the user to specify "/*" for this. | ||
350 | saveFolderContentsOnly = true; | ||
351 | } | ||
269 | 352 | ||
270 | m_invPath = String.Empty; | 353 | m_invPath = String.Empty; |
271 | for (int i = 0; i <= maxComponentIndex; i++) | 354 | for (int i = 0; i <= maxComponentIndex; i++) |
@@ -283,7 +366,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
283 | { | 366 | { |
284 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); | 367 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); |
285 | List<InventoryFolderBase> candidateFolders | 368 | List<InventoryFolderBase> candidateFolders |
286 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); | 369 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath); |
287 | if (candidateFolders.Count > 0) | 370 | if (candidateFolders.Count > 0) |
288 | inventoryFolder = candidateFolders[0]; | 371 | inventoryFolder = candidateFolders[0]; |
289 | } | 372 | } |
@@ -297,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
297 | // We couldn't find the path indicated | 380 | // We couldn't find the path indicated |
298 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); | 381 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); |
299 | Exception e = new InventoryArchiverException(errorMessage); | 382 | Exception e = new InventoryArchiverException(errorMessage); |
300 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); | 383 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0); |
301 | throw e; | 384 | throw e; |
302 | } | 385 | } |
303 | 386 | ||
@@ -335,22 +418,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
335 | 418 | ||
336 | if (SaveAssets) | 419 | if (SaveAssets) |
337 | { | 420 | { |
338 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); | 421 | m_assetGatherer.GatherAll(); |
422 | |||
423 | m_log.DebugFormat( | ||
424 | "[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count); | ||
339 | 425 | ||
340 | AssetsRequest ar | 426 | AssetsRequest ar |
341 | = new AssetsRequest( | 427 | = new AssetsRequest( |
342 | new AssetsArchiver(m_archiveWriter), | 428 | new AssetsArchiver(m_archiveWriter), |
343 | m_assetUuids, m_scene.AssetService, | 429 | m_assetGatherer.GatheredUuids, m_scene.AssetService, |
344 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | 430 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, |
345 | options, ReceivedAllAssets); | 431 | options, ReceivedAllAssets); |
346 | 432 | ||
347 | Util.FireAndForget(o => ar.Execute()); | 433 | WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name)); |
348 | } | 434 | } |
349 | else | 435 | else |
350 | { | 436 | { |
351 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); | 437 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified"); |
352 | 438 | ||
353 | ReceivedAllAssets(new List<UUID>(), new List<UUID>()); | 439 | ReceivedAllAssets(new List<UUID>(), new List<UUID>(), false); |
354 | } | 440 | } |
355 | } | 441 | } |
356 | catch (Exception) | 442 | catch (Exception) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 849449b..8847414 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -34,7 +34,6 @@ using NDesk.Options; | |||
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Communications; | ||
38 | using OpenSim.Framework.Console; | 37 | using OpenSim.Framework.Console; |
39 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
@@ -57,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
57 | // public bool DisablePresenceChecks { get; set; } | 56 | // public bool DisablePresenceChecks { get; set; } |
58 | 57 | ||
59 | public event InventoryArchiveSaved OnInventoryArchiveSaved; | 58 | public event InventoryArchiveSaved OnInventoryArchiveSaved; |
59 | public event InventoryArchiveLoaded OnInventoryArchiveLoaded; | ||
60 | 60 | ||
61 | /// <summary> | 61 | /// <summary> |
62 | /// The file to load and save inventory if no filename has been specified | 62 | /// The file to load and save inventory if no filename has been specified |
@@ -64,9 +64,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
64 | protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar"; | 64 | protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar"; |
65 | 65 | ||
66 | /// <value> | 66 | /// <value> |
67 | /// Pending save completions initiated from the console | 67 | /// Pending save and load completions initiated from the console |
68 | /// </value> | 68 | /// </value> |
69 | protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); | 69 | protected List<UUID> m_pendingConsoleTasks = new List<UUID>(); |
70 | 70 | ||
71 | /// <value> | 71 | /// <value> |
72 | /// All scenes that this module knows about | 72 | /// All scenes that this module knows about |
@@ -111,6 +111,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
111 | { | 111 | { |
112 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); | 112 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); |
113 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; | 113 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; |
114 | OnInventoryArchiveLoaded += LoadInvConsoleCommandCompleted; | ||
114 | 115 | ||
115 | scene.AddCommand( | 116 | scene.AddCommand( |
116 | "Archiving", this, "load iar", | 117 | "Archiving", this, "load iar", |
@@ -139,7 +140,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
139 | + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine | 140 | + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine |
140 | + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine | 141 | + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine |
141 | + "-v|--verbose extra debug messages.\n" | 142 | + "-v|--verbose extra debug messages.\n" |
142 | + "--noassets stops assets being saved to the IAR.", | 143 | + "--noassets stops assets being saved to the IAR." |
144 | + "--perm=<permissions> stops items with insufficient permissions from being saved to the IAR.\n" | ||
145 | + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n", | ||
143 | HandleSaveInvConsoleCommand); | 146 | HandleSaveInvConsoleCommand); |
144 | 147 | ||
145 | m_aScene = scene; | 148 | m_aScene = scene; |
@@ -175,22 +178,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
175 | /// Trigger the inventory archive saved event. | 178 | /// Trigger the inventory archive saved event. |
176 | /// </summary> | 179 | /// </summary> |
177 | protected internal void TriggerInventoryArchiveSaved( | 180 | protected internal void TriggerInventoryArchiveSaved( |
178 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 181 | UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
179 | Exception reportedException) | 182 | Exception reportedException, int SaveCount, int FilterCount) |
180 | { | 183 | { |
181 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; | 184 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; |
182 | if (handlerInventoryArchiveSaved != null) | 185 | if (handlerInventoryArchiveSaved != null) |
183 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); | 186 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException, SaveCount , FilterCount); |
187 | } | ||
188 | |||
189 | /// <summary> | ||
190 | /// Trigger the inventory archive loaded event. | ||
191 | /// </summary> | ||
192 | protected internal void TriggerInventoryArchiveLoaded( | ||
193 | UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream, | ||
194 | Exception reportedException, int LoadCount) | ||
195 | { | ||
196 | InventoryArchiveLoaded handlerInventoryArchiveLoaded = OnInventoryArchiveLoaded; | ||
197 | if (handlerInventoryArchiveLoaded != null) | ||
198 | handlerInventoryArchiveLoaded(id, succeeded, userInfo, invPath, loadStream, reportedException, LoadCount); | ||
184 | } | 199 | } |
185 | 200 | ||
186 | public bool ArchiveInventory( | 201 | public bool ArchiveInventory( |
187 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | 202 | UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream) |
188 | { | 203 | { |
189 | return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); | 204 | return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); |
190 | } | 205 | } |
191 | 206 | ||
192 | public bool ArchiveInventory( | 207 | public bool ArchiveInventory( |
193 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | 208 | UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream, |
194 | Dictionary<string, object> options) | 209 | Dictionary<string, object> options) |
195 | { | 210 | { |
196 | if (m_scenes.Count > 0) | 211 | if (m_scenes.Count > 0) |
@@ -230,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
230 | } | 245 | } |
231 | 246 | ||
232 | public bool ArchiveInventory( | 247 | public bool ArchiveInventory( |
233 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | 248 | UUID id, string firstName, string lastName, string invPath, string pass, string savePath, |
234 | Dictionary<string, object> options) | 249 | Dictionary<string, object> options) |
235 | { | 250 | { |
236 | // if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath)) | 251 | // if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath)) |
@@ -272,13 +287,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
272 | return false; | 287 | return false; |
273 | } | 288 | } |
274 | 289 | ||
275 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) | 290 | public bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream) |
276 | { | 291 | { |
277 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); | 292 | return DearchiveInventory(id, firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); |
278 | } | 293 | } |
279 | 294 | ||
280 | public bool DearchiveInventory( | 295 | public bool DearchiveInventory( |
281 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | 296 | UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream, |
282 | Dictionary<string, object> options) | 297 | Dictionary<string, object> options) |
283 | { | 298 | { |
284 | if (m_scenes.Count > 0) | 299 | if (m_scenes.Count > 0) |
@@ -294,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
294 | 309 | ||
295 | try | 310 | try |
296 | { | 311 | { |
297 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); | 312 | request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge); |
298 | } | 313 | } |
299 | catch (EntryPointNotFoundException e) | 314 | catch (EntryPointNotFoundException e) |
300 | { | 315 | { |
@@ -326,7 +341,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
326 | } | 341 | } |
327 | 342 | ||
328 | public bool DearchiveInventory( | 343 | public bool DearchiveInventory( |
329 | string firstName, string lastName, string invPath, string pass, string loadPath, | 344 | UUID id, string firstName, string lastName, string invPath, string pass, string loadPath, |
330 | Dictionary<string, object> options) | 345 | Dictionary<string, object> options) |
331 | { | 346 | { |
332 | if (m_scenes.Count > 0) | 347 | if (m_scenes.Count > 0) |
@@ -342,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
342 | 357 | ||
343 | try | 358 | try |
344 | { | 359 | { |
345 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); | 360 | request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge); |
346 | } | 361 | } |
347 | catch (EntryPointNotFoundException e) | 362 | catch (EntryPointNotFoundException e) |
348 | { | 363 | { |
@@ -378,6 +393,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
378 | { | 393 | { |
379 | try | 394 | try |
380 | { | 395 | { |
396 | UUID id = UUID.Random(); | ||
397 | |||
381 | Dictionary<string, object> options = new Dictionary<string, object>(); | 398 | Dictionary<string, object> options = new Dictionary<string, object>(); |
382 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); | 399 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); |
383 | 400 | ||
@@ -400,10 +417,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
400 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", | 417 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", |
401 | loadPath, invPath, firstName, lastName); | 418 | loadPath, invPath, firstName, lastName); |
402 | 419 | ||
403 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) | 420 | lock (m_pendingConsoleTasks) |
404 | m_log.InfoFormat( | 421 | m_pendingConsoleTasks.Add(id); |
405 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", | 422 | |
406 | loadPath, firstName, lastName); | 423 | DearchiveInventory(id, firstName, lastName, invPath, pass, loadPath, options); |
407 | } | 424 | } |
408 | catch (InventoryArchiverException e) | 425 | catch (InventoryArchiverException e) |
409 | { | 426 | { |
@@ -417,7 +434,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
417 | /// <param name="cmdparams"></param> | 434 | /// <param name="cmdparams"></param> |
418 | protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) | 435 | protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) |
419 | { | 436 | { |
420 | Guid id = Guid.NewGuid(); | 437 | UUID id = UUID.Random(); |
421 | 438 | ||
422 | Dictionary<string, object> options = new Dictionary<string, object>(); | 439 | Dictionary<string, object> options = new Dictionary<string, object>(); |
423 | 440 | ||
@@ -439,6 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
439 | options["excludefolders"] = new List<String>(); | 456 | options["excludefolders"] = new List<String>(); |
440 | ((List<String>)options["excludefolders"]).Add(v); | 457 | ((List<String>)options["excludefolders"]).Add(v); |
441 | }); | 458 | }); |
459 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | ||
442 | 460 | ||
443 | List<string> mainParams = ops.Parse(cmdparams); | 461 | List<string> mainParams = ops.Parse(cmdparams); |
444 | 462 | ||
@@ -464,8 +482,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
464 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", | 482 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", |
465 | savePath, invPath, firstName, lastName); | 483 | savePath, invPath, firstName, lastName); |
466 | 484 | ||
467 | lock (m_pendingConsoleSaves) | 485 | lock (m_pendingConsoleTasks) |
468 | m_pendingConsoleSaves.Add(id); | 486 | m_pendingConsoleTasks.Add(id); |
469 | 487 | ||
470 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); | 488 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); |
471 | } | 489 | } |
@@ -476,20 +494,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
476 | } | 494 | } |
477 | 495 | ||
478 | private void SaveInvConsoleCommandCompleted( | 496 | private void SaveInvConsoleCommandCompleted( |
479 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 497 | UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
480 | Exception reportedException) | 498 | Exception reportedException, int SaveCount, int FilterCount) |
481 | { | 499 | { |
482 | lock (m_pendingConsoleSaves) | 500 | lock (m_pendingConsoleTasks) |
483 | { | 501 | { |
484 | if (m_pendingConsoleSaves.Contains(id)) | 502 | if (m_pendingConsoleTasks.Contains(id)) |
485 | m_pendingConsoleSaves.Remove(id); | 503 | m_pendingConsoleTasks.Remove(id); |
486 | else | 504 | else |
487 | return; | 505 | return; |
488 | } | 506 | } |
489 | 507 | ||
490 | if (succeeded) | 508 | if (succeeded) |
491 | { | 509 | { |
492 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); | 510 | // Report success and include item count and filter count (Skipped items due to --perm or --exclude switches) |
511 | if(FilterCount == 0) | ||
512 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}", SaveCount, userInfo.FirstName, userInfo.LastName); | ||
513 | else | ||
514 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}. Skipped {3} items due to exclude and/or perm switches", SaveCount, userInfo.FirstName, userInfo.LastName, FilterCount); | ||
493 | } | 515 | } |
494 | else | 516 | else |
495 | { | 517 | { |
@@ -499,6 +521,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
499 | } | 521 | } |
500 | } | 522 | } |
501 | 523 | ||
524 | private void LoadInvConsoleCommandCompleted( | ||
525 | UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream, | ||
526 | Exception reportedException, int LoadCount) | ||
527 | { | ||
528 | lock (m_pendingConsoleTasks) | ||
529 | { | ||
530 | if (m_pendingConsoleTasks.Contains(id)) | ||
531 | m_pendingConsoleTasks.Remove(id); | ||
532 | else | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | if (succeeded) | ||
537 | { | ||
538 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Loaded {0} items from archive {1} for {2} {3}", LoadCount, invPath, userInfo.FirstName, userInfo.LastName); | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | m_log.ErrorFormat( | ||
543 | "[INVENTORY ARCHIVER]: Archive load for {0} {1} failed - {2}", | ||
544 | userInfo.FirstName, userInfo.LastName, reportedException.Message); | ||
545 | } | ||
546 | } | ||
547 | |||
502 | /// <summary> | 548 | /// <summary> |
503 | /// Get user information for the given name. | 549 | /// Get user information for the given name. |
504 | /// </summary> | 550 | /// </summary> |
@@ -536,7 +582,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
536 | } | 582 | } |
537 | catch (Exception e) | 583 | catch (Exception e) |
538 | { | 584 | { |
539 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message); | 585 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e); |
540 | return null; | 586 | return null; |
541 | } | 587 | } |
542 | } | 588 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index 6eb3605..c2e645f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs | |||
@@ -36,137 +36,19 @@ using OpenSim.Data; | |||
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Serialization; | 37 | using OpenSim.Framework.Serialization; |
38 | using OpenSim.Framework.Serialization.External; | 38 | using OpenSim.Framework.Serialization.External; |
39 | using OpenSim.Framework.Communications; | ||
40 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | 39 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; |
41 | using OpenSim.Region.CoreModules.World.Serialiser; | 40 | using OpenSim.Region.CoreModules.World.Serialiser; |
42 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 42 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 43 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 45 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 47 | { |
50 | [TestFixture] | 48 | [TestFixture] |
51 | public class PathTests : InventoryArchiveTestCase | 49 | public class InventoryArchiveLoadPathTests : InventoryArchiveTestCase |
52 | { | 50 | { |
53 | /// <summary> | 51 | /// <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. | 52 | /// Test loading an IAR to various different inventory paths. |
171 | /// </summary> | 53 | /// </summary> |
172 | [Test] | 54 | [Test] |
@@ -185,26 +67,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
185 | 67 | ||
186 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); | 68 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood"); |
187 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); | 69 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); |
188 | 70 | ||
189 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); | 71 | archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); |
190 | InventoryItemBase foundItem1 | 72 | InventoryItemBase foundItem1 |
191 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | 73 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); |
192 | 74 | ||
193 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); | 75 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); |
194 | 76 | ||
195 | // Now try loading to a root child folder | 77 | // Now try loading to a root child folder |
196 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); | 78 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false); |
197 | MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); | 79 | MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); |
198 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); | 80 | archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); |
199 | 81 | ||
200 | InventoryItemBase foundItem2 | 82 | InventoryItemBase foundItem2 |
201 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); | 83 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); |
202 | Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); | 84 | Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); |
203 | 85 | ||
204 | // Now try loading to a more deeply nested folder | 86 | // Now try loading to a more deeply nested folder |
205 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); | 87 | UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false); |
206 | archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); | 88 | archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); |
207 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); | 89 | archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); |
208 | 90 | ||
209 | InventoryItemBase foundItem3 | 91 | InventoryItemBase foundItem3 |
210 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); | 92 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); |
@@ -226,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
226 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 108 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
227 | 109 | ||
228 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); | 110 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); |
229 | archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); | 111 | archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); |
230 | 112 | ||
231 | InventoryItemBase foundItem1 | 113 | InventoryItemBase foundItem1 |
232 | = InventoryArchiveUtils.FindItemByPath( | 114 | = InventoryArchiveUtils.FindItemByPath( |
@@ -287,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
287 | item1.AssetID = asset1.FullID; | 169 | item1.AssetID = asset1.FullID; |
288 | item1.ID = item1Id; | 170 | item1.ID = item1Id; |
289 | InventoryFolderBase objsFolder | 171 | InventoryFolderBase objsFolder |
290 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; | 172 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, userId, "Objects")[0]; |
291 | item1.Folder = objsFolder.ID; | 173 | item1.Folder = objsFolder.ID; |
292 | scene.AddInventoryItem(item1); | 174 | scene.AddInventoryItem(item1); |
293 | 175 | ||
@@ -296,13 +178,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
296 | 178 | ||
297 | mre.Reset(); | 179 | mre.Reset(); |
298 | archiverModule.ArchiveInventory( | 180 | archiverModule.ArchiveInventory( |
299 | Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); | 181 | UUID.Random(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); |
300 | mre.WaitOne(60000, false); | 182 | mre.WaitOne(60000, false); |
301 | 183 | ||
302 | // LOAD ITEM | 184 | // LOAD ITEM |
303 | MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); | 185 | MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); |
304 | 186 | ||
305 | archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); | 187 | archiverModule.DearchiveInventory(UUID.Random(), userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); |
306 | 188 | ||
307 | InventoryItemBase foundItem1 | 189 | InventoryItemBase foundItem1 |
308 | = InventoryArchiveUtils.FindItemByPath( | 190 | = InventoryArchiveUtils.FindItemByPath( |
@@ -345,40 +227,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
345 | 227 | ||
346 | { | 228 | { |
347 | // Test replication of path1 | 229 | // Test replication of path1 |
348 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 230 | new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
349 | .ReplicateArchivePathToUserInventory( | 231 | .ReplicateArchivePathToUserInventory( |
350 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 232 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
351 | foldersCreated, nodesLoaded); | 233 | foldersCreated, nodesLoaded); |
352 | 234 | ||
353 | List<InventoryFolderBase> folder1Candidates | 235 | List<InventoryFolderBase> folder1Candidates |
354 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); | 236 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); |
355 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); | 237 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); |
356 | 238 | ||
357 | InventoryFolderBase folder1 = folder1Candidates[0]; | 239 | InventoryFolderBase folder1 = folder1Candidates[0]; |
358 | List<InventoryFolderBase> folder2aCandidates | 240 | List<InventoryFolderBase> folder2aCandidates |
359 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); | 241 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); |
360 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); | 242 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); |
361 | } | 243 | } |
362 | 244 | ||
363 | { | 245 | { |
364 | // Test replication of path2 | 246 | // Test replication of path2 |
365 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 247 | new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
366 | .ReplicateArchivePathToUserInventory( | 248 | .ReplicateArchivePathToUserInventory( |
367 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 249 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
368 | foldersCreated, nodesLoaded); | 250 | foldersCreated, nodesLoaded); |
369 | 251 | ||
370 | List<InventoryFolderBase> folder1Candidates | 252 | List<InventoryFolderBase> folder1Candidates |
371 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); | 253 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1Name); |
372 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); | 254 | Assert.That(folder1Candidates.Count, Is.EqualTo(1)); |
373 | 255 | ||
374 | InventoryFolderBase folder1 = folder1Candidates[0]; | 256 | InventoryFolderBase folder1 = folder1Candidates[0]; |
375 | 257 | ||
376 | List<InventoryFolderBase> folder2aCandidates | 258 | List<InventoryFolderBase> folder2aCandidates |
377 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2aName); | 259 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2aName); |
378 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); | 260 | Assert.That(folder2aCandidates.Count, Is.EqualTo(1)); |
379 | 261 | ||
380 | List<InventoryFolderBase> folder2bCandidates | 262 | List<InventoryFolderBase> folder2bCandidates |
381 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1, folder2bName); | 263 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1, folder2bName); |
382 | Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); | 264 | Assert.That(folder2bCandidates.Count, Is.EqualTo(1)); |
383 | } | 265 | } |
384 | } | 266 | } |
@@ -401,20 +283,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
401 | 283 | ||
402 | InventoryFolderBase folder1 | 284 | InventoryFolderBase folder1 |
403 | = UserInventoryHelpers.CreateInventoryFolder( | 285 | = UserInventoryHelpers.CreateInventoryFolder( |
404 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 286 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); |
405 | 287 | ||
406 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); | 288 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); |
407 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 289 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
408 | 290 | ||
409 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | 291 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); |
410 | 292 | ||
411 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 293 | new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
412 | .ReplicateArchivePathToUserInventory( | 294 | .ReplicateArchivePathToUserInventory( |
413 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 295 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
414 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 296 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
415 | 297 | ||
416 | List<InventoryFolderBase> folder1PostCandidates | 298 | List<InventoryFolderBase> folder1PostCandidates |
417 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 299 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); |
418 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); | 300 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(2)); |
419 | 301 | ||
420 | // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. | 302 | // FIXME: Temporarily, we're going to do something messy to make sure we pick up the created folder. |
@@ -430,7 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
430 | // Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); | 312 | // Assert.That(folder1Post.ID, Is.EqualTo(folder1.ID)); |
431 | 313 | ||
432 | List<InventoryFolderBase> folder2PostCandidates | 314 | List<InventoryFolderBase> folder2PostCandidates |
433 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1Post, "b"); | 315 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1Post, "b"); |
434 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | 316 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); |
435 | } | 317 | } |
436 | 318 | ||
@@ -452,26 +334,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
452 | 334 | ||
453 | InventoryFolderBase folder1 | 335 | InventoryFolderBase folder1 |
454 | = UserInventoryHelpers.CreateInventoryFolder( | 336 | = UserInventoryHelpers.CreateInventoryFolder( |
455 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 337 | scene.InventoryService, ua1.PrincipalID, folder1ExistingName, false); |
456 | 338 | ||
457 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); | 339 | string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1ExistingName, UUID.Random()); |
458 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 340 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
459 | 341 | ||
460 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | 342 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); |
461 | 343 | ||
462 | new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) | 344 | new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) |
463 | .ReplicateArchivePathToUserInventory( | 345 | .ReplicateArchivePathToUserInventory( |
464 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 346 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
465 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 347 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
466 | 348 | ||
467 | List<InventoryFolderBase> folder1PostCandidates | 349 | List<InventoryFolderBase> folder1PostCandidates |
468 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); | 350 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); |
469 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); | 351 | Assert.That(folder1PostCandidates.Count, Is.EqualTo(1)); |
470 | Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); | 352 | Assert.That(folder1PostCandidates[0].ID, Is.EqualTo(folder1.ID)); |
471 | 353 | ||
472 | List<InventoryFolderBase> folder2PostCandidates | 354 | List<InventoryFolderBase> folder2PostCandidates |
473 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, folder1PostCandidates[0], "b"); | 355 | = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, folder1PostCandidates[0], "b"); |
474 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); | 356 | Assert.That(folder2PostCandidates.Count, Is.EqualTo(1)); |
475 | } | 357 | } |
476 | } | 358 | } |
477 | } \ No newline at end of file | 359 | } |
360 | |||
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..57b4f80 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs | |||
@@ -0,0 +1,192 @@ | |||
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.Region.CoreModules.Avatar.Inventory.Archiver; | ||
40 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
43 | using OpenSim.Services.Interfaces; | ||
44 | using OpenSim.Tests.Common; | ||
45 | |||
46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | ||
47 | { | ||
48 | [TestFixture] | ||
49 | public class InventoryArchiveLoadTests : InventoryArchiveTestCase | ||
50 | { | ||
51 | protected TestScene m_scene; | ||
52 | protected InventoryArchiverModule m_archiverModule; | ||
53 | |||
54 | [SetUp] | ||
55 | public override void SetUp() | ||
56 | { | ||
57 | base.SetUp(); | ||
58 | |||
59 | SerialiserModule serialiserModule = new SerialiserModule(); | ||
60 | m_archiverModule = new InventoryArchiverModule(); | ||
61 | |||
62 | m_scene = new SceneHelpers().SetupScene(); | ||
63 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | ||
64 | } | ||
65 | |||
66 | [Test] | ||
67 | public void TestLoadCoalesecedItem() | ||
68 | { | ||
69 | TestHelpers.InMethod(); | ||
70 | // TestHelpers.EnableLogging(); | ||
71 | |||
72 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); | ||
73 | m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); | ||
74 | |||
75 | InventoryItemBase coaItem | ||
76 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); | ||
77 | |||
78 | Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); | ||
79 | |||
80 | string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); | ||
81 | |||
82 | CoalescedSceneObjects coa; | ||
83 | bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); | ||
84 | |||
85 | Assert.That(readResult, Is.True); | ||
86 | Assert.That(coa.Count, Is.EqualTo(2)); | ||
87 | |||
88 | List<SceneObjectGroup> coaObjects = coa.Objects; | ||
89 | Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); | ||
90 | Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); | ||
91 | |||
92 | Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); | ||
93 | Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); | ||
94 | } | ||
95 | |||
96 | /// <summary> | ||
97 | /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized | ||
98 | /// objects. | ||
99 | /// </summary> | ||
100 | [Test] | ||
101 | public void TestLoadIarCreatorAccountPresent() | ||
102 | { | ||
103 | TestHelpers.InMethod(); | ||
104 | // log4net.Config.XmlConfigurator.Configure(); | ||
105 | |||
106 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); | ||
107 | |||
108 | m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); | ||
109 | InventoryItemBase foundItem1 | ||
110 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); | ||
111 | |||
112 | Assert.That( | ||
113 | foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), | ||
114 | "Loaded item non-uuid creator doesn't match original"); | ||
115 | Assert.That( | ||
116 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), | ||
117 | "Loaded item uuid creator doesn't match original"); | ||
118 | Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), | ||
119 | "Loaded item owner doesn't match inventory reciever"); | ||
120 | |||
121 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
122 | string xmlData = Utils.BytesToString(asset1.Data); | ||
123 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
124 | |||
125 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); | ||
126 | } | ||
127 | |||
128 | // /// <summary> | ||
129 | // /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
130 | // /// an account exists with the same name as the creator, though not the same id. | ||
131 | // /// </summary> | ||
132 | // [Test] | ||
133 | // public void TestLoadIarV0_1SameNameCreator() | ||
134 | // { | ||
135 | // TestHelpers.InMethod(); | ||
136 | // TestHelpers.EnableLogging(); | ||
137 | // | ||
138 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); | ||
139 | // UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); | ||
140 | // | ||
141 | // m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); | ||
142 | // InventoryItemBase foundItem1 | ||
143 | // = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
144 | // | ||
145 | // Assert.That( | ||
146 | // foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), | ||
147 | // "Loaded item non-uuid creator doesn't match original"); | ||
148 | // Assert.That( | ||
149 | // foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), | ||
150 | // "Loaded item uuid creator doesn't match original"); | ||
151 | // Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), | ||
152 | // "Loaded item owner doesn't match inventory reciever"); | ||
153 | // | ||
154 | // AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
155 | // string xmlData = Utils.BytesToString(asset1.Data); | ||
156 | // SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
157 | // | ||
158 | // Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); | ||
159 | // } | ||
160 | |||
161 | /// <summary> | ||
162 | /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where | ||
163 | /// the creator or an account with the creator's name does not exist within the system. | ||
164 | /// </summary> | ||
165 | [Test] | ||
166 | public void TestLoadIarV0_1AbsentCreator() | ||
167 | { | ||
168 | TestHelpers.InMethod(); | ||
169 | // log4net.Config.XmlConfigurator.Configure(); | ||
170 | |||
171 | UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password"); | ||
172 | m_archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); | ||
173 | |||
174 | InventoryItemBase foundItem1 | ||
175 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); | ||
176 | |||
177 | Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); | ||
178 | Assert.That( | ||
179 | foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), | ||
180 | "Loaded item non-uuid creator doesn't match that of the loading user"); | ||
181 | Assert.That( | ||
182 | foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), | ||
183 | "Loaded item uuid creator doesn't match that of the loading user"); | ||
184 | |||
185 | AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); | ||
186 | string xmlData = Utils.BytesToString(asset1.Data); | ||
187 | SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
188 | |||
189 | Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); | ||
190 | } | ||
191 | } | ||
192 | } \ 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..7265405 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs | |||
@@ -36,19 +36,17 @@ using OpenSim.Data; | |||
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Serialization; | 37 | using OpenSim.Framework.Serialization; |
38 | using OpenSim.Framework.Serialization.External; | 38 | using OpenSim.Framework.Serialization.External; |
39 | using OpenSim.Framework.Communications; | ||
40 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | 39 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; |
41 | using OpenSim.Region.CoreModules.World.Serialiser; | 40 | using OpenSim.Region.CoreModules.World.Serialiser; |
42 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 42 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 43 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 45 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 47 | { |
50 | [TestFixture] | 48 | [TestFixture] |
51 | public class InventoryArchiverTests : InventoryArchiveTestCase | 49 | public class InventoryArchiveSaveTests : InventoryArchiveTestCase |
52 | { | 50 | { |
53 | protected TestScene m_scene; | 51 | protected TestScene m_scene; |
54 | protected InventoryArchiverModule m_archiverModule; | 52 | protected InventoryArchiverModule m_archiverModule; |
@@ -64,36 +62,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
64 | m_scene = new SceneHelpers().SetupScene(); | 62 | m_scene = new SceneHelpers().SetupScene(); |
65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | 63 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); |
66 | } | 64 | } |
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 | 65 | ||
98 | /// <summary> | 66 | /// <summary> |
99 | /// Test that the IAR has the required files in the right order. | 67 | /// Test that the IAR has the required files in the right order. |
@@ -115,12 +83,145 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
115 | byte[] data = tar.ReadEntry(out filePath, out tarEntryType); | 83 | byte[] data = tar.ReadEntry(out filePath, out tarEntryType); |
116 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | 84 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); |
117 | 85 | ||
118 | InventoryArchiveReadRequest iarr | 86 | InventoryArchiveReadRequest iarr |
119 | = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); | 87 | = new InventoryArchiveReadRequest(UUID.Random(), null, null, null, null, null, null, (Stream)null, false); |
120 | iarr.LoadControlFile(filePath, data); | 88 | iarr.LoadControlFile(filePath, data); |
121 | 89 | ||
122 | Assert.That(iarr.ControlFileLoaded, Is.True); | 90 | Assert.That(iarr.ControlFileLoaded, Is.True); |
123 | } | 91 | } |
92 | |||
93 | [Test] | ||
94 | public void TestSaveRootFolderToIar() | ||
95 | { | ||
96 | TestHelpers.InMethod(); | ||
97 | // TestHelpers.EnableLogging(); | ||
98 | |||
99 | string userFirstName = "Jock"; | ||
100 | string userLastName = "Stirrup"; | ||
101 | string userPassword = "troll"; | ||
102 | UUID userId = TestHelpers.ParseTail(0x20); | ||
103 | |||
104 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
105 | |||
106 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
107 | m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; | ||
108 | |||
109 | mre.Reset(); | ||
110 | m_archiverModule.ArchiveInventory( | ||
111 | UUID.Random(), userFirstName, userLastName, "/", userPassword, archiveWriteStream); | ||
112 | mre.WaitOne(60000, false); | ||
113 | |||
114 | // Test created iar | ||
115 | byte[] archive = archiveWriteStream.ToArray(); | ||
116 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
117 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
118 | |||
119 | // InventoryArchiveUtils. | ||
120 | bool gotObjectsFolder = false; | ||
121 | |||
122 | string objectsFolderName | ||
123 | = string.Format( | ||
124 | "{0}{1}", | ||
125 | ArchiveConstants.INVENTORY_PATH, | ||
126 | InventoryArchiveWriteRequest.CreateArchiveFolderName( | ||
127 | UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, userId, "Objects"))); | ||
128 | |||
129 | string filePath; | ||
130 | TarArchiveReader.TarEntryType tarEntryType; | ||
131 | |||
132 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
133 | { | ||
134 | // Console.WriteLine("Got {0}", filePath); | ||
135 | |||
136 | // Lazily, we only bother to look for the system objects folder created when we call CreateUserWithInventory() | ||
137 | // XXX: But really we need to stop all that stuff being created in tests or check for such folders | ||
138 | // more thoroughly | ||
139 | if (filePath == objectsFolderName) | ||
140 | gotObjectsFolder = true; | ||
141 | } | ||
142 | |||
143 | Assert.That(gotObjectsFolder, Is.True); | ||
144 | } | ||
145 | |||
146 | [Test] | ||
147 | public void TestSaveNonRootFolderToIar() | ||
148 | { | ||
149 | TestHelpers.InMethod(); | ||
150 | // TestHelpers.EnableLogging(); | ||
151 | |||
152 | string userFirstName = "Jock"; | ||
153 | string userLastName = "Stirrup"; | ||
154 | string userPassword = "troll"; | ||
155 | UUID userId = TestHelpers.ParseTail(0x20); | ||
156 | |||
157 | UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | ||
158 | |||
159 | // Create base folder | ||
160 | InventoryFolderBase f1 | ||
161 | = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1", true); | ||
162 | |||
163 | // Create item1 | ||
164 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Dog Object", 0x5); | ||
165 | InventoryItemBase i1 = UserInventoryHelpers.AddInventoryItem(m_scene, so1, 0x50, 0x60, "f1"); | ||
166 | |||
167 | // Create embedded folder | ||
168 | InventoryFolderBase f1_1 | ||
169 | = UserInventoryHelpers.CreateInventoryFolder(m_scene.InventoryService, userId, "f1/f1.1", true); | ||
170 | |||
171 | // Create embedded item | ||
172 | SceneObjectGroup so1_1 = SceneHelpers.CreateSceneObject(1, userId, "My Little Cat Object", 0x6); | ||
173 | InventoryItemBase i2 = UserInventoryHelpers.AddInventoryItem(m_scene, so1_1, 0x500, 0x600, "f1/f1.1"); | ||
174 | |||
175 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
176 | m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; | ||
177 | |||
178 | mre.Reset(); | ||
179 | m_archiverModule.ArchiveInventory( | ||
180 | UUID.Random(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream); | ||
181 | mre.WaitOne(60000, false); | ||
182 | |||
183 | // Test created iar | ||
184 | byte[] archive = archiveWriteStream.ToArray(); | ||
185 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
186 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
187 | |||
188 | // InventoryArchiveUtils. | ||
189 | bool gotf1 = false, gotf1_1 = false, gotso1 = false, gotso2 = false; | ||
190 | |||
191 | string f1FileName | ||
192 | = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1)); | ||
193 | string f1_1FileName | ||
194 | = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveFolderName(f1_1)); | ||
195 | string so1FileName | ||
196 | = string.Format("{0}{1}", f1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i1)); | ||
197 | string so2FileName | ||
198 | = string.Format("{0}{1}", f1_1FileName, InventoryArchiveWriteRequest.CreateArchiveItemName(i2)); | ||
199 | |||
200 | string filePath; | ||
201 | TarArchiveReader.TarEntryType tarEntryType; | ||
202 | |||
203 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | ||
204 | { | ||
205 | // Console.WriteLine("Got {0}", filePath); | ||
206 | |||
207 | if (filePath == f1FileName) | ||
208 | gotf1 = true; | ||
209 | else if (filePath == f1_1FileName) | ||
210 | gotf1_1 = true; | ||
211 | else if (filePath == so1FileName) | ||
212 | gotso1 = true; | ||
213 | else if (filePath == so2FileName) | ||
214 | gotso2 = true; | ||
215 | } | ||
216 | |||
217 | // Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
218 | Assert.That(gotf1, Is.True); | ||
219 | Assert.That(gotf1_1, Is.True); | ||
220 | Assert.That(gotso1, Is.True); | ||
221 | Assert.That(gotso2, Is.True); | ||
222 | |||
223 | // TODO: Test presence of more files and contents of files. | ||
224 | } | ||
124 | 225 | ||
125 | /// <summary> | 226 | /// <summary> |
126 | /// Test saving a single inventory item to an IAR | 227 | /// Test saving a single inventory item to an IAR |
@@ -155,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
155 | item1.AssetID = asset1.FullID; | 256 | item1.AssetID = asset1.FullID; |
156 | item1.ID = item1Id; | 257 | item1.ID = item1Id; |
157 | InventoryFolderBase objsFolder | 258 | InventoryFolderBase objsFolder |
158 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | 259 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; |
159 | item1.Folder = objsFolder.ID; | 260 | item1.Folder = objsFolder.ID; |
160 | m_scene.AddInventoryItem(item1); | 261 | m_scene.AddInventoryItem(item1); |
161 | 262 | ||
@@ -164,7 +265,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
164 | 265 | ||
165 | mre.Reset(); | 266 | mre.Reset(); |
166 | m_archiverModule.ArchiveInventory( | 267 | m_archiverModule.ArchiveInventory( |
167 | Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); | 268 | UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); |
168 | mre.WaitOne(60000, false); | 269 | mre.WaitOne(60000, false); |
169 | 270 | ||
170 | byte[] archive = archiveWriteStream.ToArray(); | 271 | byte[] archive = archiveWriteStream.ToArray(); |
@@ -250,7 +351,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
250 | item1.AssetID = asset1.FullID; | 351 | item1.AssetID = asset1.FullID; |
251 | item1.ID = item1Id; | 352 | item1.ID = item1Id; |
252 | InventoryFolderBase objsFolder | 353 | InventoryFolderBase objsFolder |
253 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; | 354 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, userId, "Objects")[0]; |
254 | item1.Folder = objsFolder.ID; | 355 | item1.Folder = objsFolder.ID; |
255 | m_scene.AddInventoryItem(item1); | 356 | m_scene.AddInventoryItem(item1); |
256 | 357 | ||
@@ -261,7 +362,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
261 | 362 | ||
262 | // When we're not saving assets, archiving is being done synchronously. | 363 | // When we're not saving assets, archiving is being done synchronously. |
263 | m_archiverModule.ArchiveInventory( | 364 | m_archiverModule.ArchiveInventory( |
264 | Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); | 365 | UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options); |
265 | 366 | ||
266 | byte[] archive = archiveWriteStream.ToArray(); | 367 | byte[] archive = archiveWriteStream.ToArray(); |
267 | MemoryStream archiveReadStream = new MemoryStream(archive); | 368 | MemoryStream archiveReadStream = new MemoryStream(archive); |
@@ -317,101 +418,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
317 | 418 | ||
318 | // TODO: Test presence of more files and contents of files. | 419 | // TODO: Test presence of more files and contents of files. |
319 | } | 420 | } |
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 | } | 421 | } |
417 | } \ No newline at end of file | 422 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index db78da9..519c697 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -36,14 +36,12 @@ using OpenSim.Data; | |||
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Serialization; | 37 | using OpenSim.Framework.Serialization; |
38 | using OpenSim.Framework.Serialization.External; | 38 | using OpenSim.Framework.Serialization.External; |
39 | using OpenSim.Framework.Communications; | ||
40 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | 39 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; |
41 | using OpenSim.Region.CoreModules.World.Serialiser; | 40 | using OpenSim.Region.CoreModules.World.Serialiser; |
42 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 42 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 43 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 45 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 47 | { |
@@ -163,14 +161,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
163 | scene.AddInventoryItem(coaItem); | 161 | scene.AddInventoryItem(coaItem); |
164 | 162 | ||
165 | archiverModule.ArchiveInventory( | 163 | archiverModule.ArchiveInventory( |
166 | Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream); | 164 | UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream); |
167 | 165 | ||
168 | m_iarStreamBytes = archiveWriteStream.ToArray(); | 166 | m_iarStreamBytes = archiveWriteStream.ToArray(); |
169 | } | 167 | } |
170 | 168 | ||
171 | protected void SaveCompleted( | 169 | protected void SaveCompleted( |
172 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 170 | UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
173 | Exception reportedException) | 171 | Exception reportedException, int SaveCount, int FilterCount) |
174 | { | 172 | { |
175 | mre.Set(); | 173 | mre.Set(); |
176 | } | 174 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index bcb7f42..bba48cc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -47,10 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
47 | 47 | ||
48 | /// <summary> | 48 | /// <summary> |
49 | private List<Scene> m_Scenelist = new List<Scene>(); | 49 | private List<Scene> m_Scenelist = new List<Scene>(); |
50 | // private Dictionary<UUID, Scene> m_AgentRegions = | ||
51 | // new Dictionary<UUID, Scene>(); | ||
52 | 50 | ||
53 | private IMessageTransferModule m_TransferModule = null; | 51 | private IMessageTransferModule m_TransferModule; |
54 | private bool m_Enabled = true; | 52 | private bool m_Enabled = true; |
55 | 53 | ||
56 | #region Region Module interface | 54 | #region Region Module interface |
@@ -81,9 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
81 | // scene.RegisterModuleInterface<IInventoryTransferModule>(this); | 79 | // scene.RegisterModuleInterface<IInventoryTransferModule>(this); |
82 | 80 | ||
83 | scene.EventManager.OnNewClient += OnNewClient; | 81 | scene.EventManager.OnNewClient += OnNewClient; |
84 | // scene.EventManager.OnClientClosed += ClientLoggedOut; | ||
85 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 82 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; |
86 | // scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; | ||
87 | } | 83 | } |
88 | 84 | ||
89 | public void RegionLoaded(Scene scene) | 85 | public void RegionLoaded(Scene scene) |
@@ -96,11 +92,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
96 | m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only"); | 92 | m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only"); |
97 | m_Enabled = false; | 93 | m_Enabled = false; |
98 | 94 | ||
99 | m_Scenelist.Clear(); | 95 | // m_Scenelist.Clear(); |
100 | scene.EventManager.OnNewClient -= OnNewClient; | 96 | // scene.EventManager.OnNewClient -= OnNewClient; |
101 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
102 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 97 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
103 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | ||
104 | } | 98 | } |
105 | } | 99 | } |
106 | } | 100 | } |
@@ -108,9 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
108 | public void RemoveRegion(Scene scene) | 102 | public void RemoveRegion(Scene scene) |
109 | { | 103 | { |
110 | scene.EventManager.OnNewClient -= OnNewClient; | 104 | scene.EventManager.OnNewClient -= OnNewClient; |
111 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
112 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 105 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
113 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | ||
114 | m_Scenelist.Remove(scene); | 106 | m_Scenelist.Remove(scene); |
115 | } | 107 | } |
116 | 108 | ||
@@ -139,11 +131,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
139 | // Inventory giving is conducted via instant message | 131 | // Inventory giving is conducted via instant message |
140 | client.OnInstantMessage += OnInstantMessage; | 132 | client.OnInstantMessage += OnInstantMessage; |
141 | } | 133 | } |
142 | |||
143 | // protected void OnSetRootAgentScene(UUID id, Scene scene) | ||
144 | // { | ||
145 | // m_AgentRegions[id] = scene; | ||
146 | // } | ||
147 | 134 | ||
148 | private Scene FindClientScene(UUID agentId) | 135 | private Scene FindClientScene(UUID agentId) |
149 | { | 136 | { |
@@ -162,8 +149,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
162 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 149 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
163 | { | 150 | { |
164 | // m_log.DebugFormat( | 151 | // m_log.DebugFormat( |
165 | // "[INVENTORY TRANSFER]: {0} IM type received from {1}", | 152 | // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", |
166 | // (InstantMessageDialog)im.dialog, client.Name); | 153 | // (InstantMessageDialog)im.dialog, client.Name, |
154 | // im.fromAgentID, im.fromAgentName, im.toAgentID); | ||
167 | 155 | ||
168 | Scene scene = FindClientScene(client.AgentId); | 156 | Scene scene = FindClientScene(client.AgentId); |
169 | 157 | ||
@@ -188,12 +176,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
188 | { | 176 | { |
189 | UUID folderID = new UUID(im.binaryBucket, 1); | 177 | UUID folderID = new UUID(im.binaryBucket, 1); |
190 | 178 | ||
191 | m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} "+ | 179 | m_log.DebugFormat( |
192 | "into agent {1}'s inventory", | 180 | "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", |
193 | folderID, new UUID(im.toAgentID)); | 181 | folderID, new UUID(im.toAgentID)); |
194 | 182 | ||
195 | InventoryFolderBase folderCopy | 183 | InventoryFolderBase folderCopy |
196 | = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); | 184 | = scene.GiveInventoryFolder(client, receipientID, client.AgentId, folderID, UUID.Zero); |
197 | 185 | ||
198 | if (folderCopy == null) | 186 | if (folderCopy == null) |
199 | { | 187 | { |
@@ -213,7 +201,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
213 | user.ControllingClient.SendBulkUpdateInventory(folderCopy); | 201 | user.ControllingClient.SendBulkUpdateInventory(folderCopy); |
214 | 202 | ||
215 | // HACK!! | 203 | // HACK!! |
216 | im.imSessionID = folderID.Guid; | 204 | // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it |
205 | // is rejected. | ||
206 | // XXX: This is probably a misuse of the session ID slot. | ||
207 | im.imSessionID = copyID.Guid; | ||
217 | } | 208 | } |
218 | else | 209 | else |
219 | { | 210 | { |
@@ -226,13 +217,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
226 | "into agent {1}'s inventory", | 217 | "into agent {1}'s inventory", |
227 | itemID, new UUID(im.toAgentID)); | 218 | itemID, new UUID(im.toAgentID)); |
228 | 219 | ||
229 | InventoryItemBase itemCopy = scene.GiveInventoryItem( | 220 | string message; |
230 | new UUID(im.toAgentID), | 221 | InventoryItemBase itemCopy = scene.GiveInventoryItem(new UUID(im.toAgentID), client.AgentId, itemID, out message); |
231 | client.AgentId, itemID); | ||
232 | 222 | ||
233 | if (itemCopy == null) | 223 | if (itemCopy == null) |
234 | { | 224 | { |
235 | client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); | 225 | client.SendAgentAlertMessage(message, false); |
236 | return; | 226 | return; |
237 | } | 227 | } |
238 | 228 | ||
@@ -243,7 +233,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
243 | user.ControllingClient.SendBulkUpdateInventory(itemCopy); | 233 | user.ControllingClient.SendBulkUpdateInventory(itemCopy); |
244 | 234 | ||
245 | // HACK!! | 235 | // HACK!! |
246 | im.imSessionID = itemID.Guid; | 236 | // Insert the ID of the copied item into the IM so that we know which item to move to trash if it |
237 | // is rejected. | ||
238 | // XXX: This is probably a misuse of the session ID slot. | ||
239 | im.imSessionID = copyID.Guid; | ||
247 | } | 240 | } |
248 | 241 | ||
249 | // Send the IM to the recipient. The item is already | 242 | // Send the IM to the recipient. The item is already |
@@ -379,7 +372,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
379 | IInventoryService invService = scene.InventoryService; | 372 | IInventoryService invService = scene.InventoryService; |
380 | 373 | ||
381 | InventoryFolderBase trashFolder = | 374 | InventoryFolderBase trashFolder = |
382 | invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); | 375 | invService.GetFolderForType(client.AgentId, FolderType.Trash); |
383 | 376 | ||
384 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip | 377 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip |
385 | 378 | ||
@@ -403,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
403 | { | 396 | { |
404 | folder = new InventoryFolderBase(inventoryID, client.AgentId); | 397 | folder = new InventoryFolderBase(inventoryID, client.AgentId); |
405 | folder = invService.GetFolder(folder); | 398 | folder = invService.GetFolder(folder); |
406 | 399 | ||
407 | if (folder != null & trashFolder != null) | 400 | if (folder != null & trashFolder != null) |
408 | { | 401 | { |
409 | previousParentFolderID = folder.ParentID; | 402 | previousParentFolderID = folder.ParentID; |
@@ -454,90 +447,61 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
454 | } | 447 | } |
455 | } | 448 | } |
456 | 449 | ||
457 | // public bool NeedSceneCacheClear(UUID agentID, Scene scene) | ||
458 | // { | ||
459 | // if (!m_AgentRegions.ContainsKey(agentID)) | ||
460 | // { | ||
461 | // // Since we can get here two ways, we need to scan | ||
462 | // // the scenes here. This is somewhat more expensive | ||
463 | // // but helps avoid a nasty bug | ||
464 | // // | ||
465 | // | ||
466 | // foreach (Scene s in m_Scenelist) | ||
467 | // { | ||
468 | // ScenePresence presence; | ||
469 | // | ||
470 | // if (s.TryGetScenePresence(agentID, out presence)) | ||
471 | // { | ||
472 | // // If the agent is in this scene, then we | ||
473 | // // are being called twice in a single | ||
474 | // // teleport. This is wasteful of cycles | ||
475 | // // but harmless due to this 2nd level check | ||
476 | // // | ||
477 | // // If the agent is found in another scene | ||
478 | // // then the list wasn't current | ||
479 | // // | ||
480 | // // If the agent is totally unknown, then what | ||
481 | // // are we even doing here?? | ||
482 | // // | ||
483 | // if (s == scene) | ||
484 | // { | ||
485 | // //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName); | ||
486 | // return true; | ||
487 | // } | ||
488 | // else | ||
489 | // { | ||
490 | // //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName); | ||
491 | // return false; | ||
492 | // } | ||
493 | // } | ||
494 | // } | ||
495 | // //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName); | ||
496 | // return true; | ||
497 | // } | ||
498 | // | ||
499 | // // The agent is left in current Scene, so we must be | ||
500 | // // going to another instance | ||
501 | // // | ||
502 | // if (m_AgentRegions[agentID] == scene) | ||
503 | // { | ||
504 | // //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName); | ||
505 | // m_AgentRegions.Remove(agentID); | ||
506 | // return true; | ||
507 | // } | ||
508 | // | ||
509 | // // Another region has claimed the agent | ||
510 | // // | ||
511 | // //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName); | ||
512 | // return false; | ||
513 | // } | ||
514 | // | ||
515 | // public void ClientLoggedOut(UUID agentID, Scene scene) | ||
516 | // { | ||
517 | // if (m_AgentRegions.ContainsKey(agentID)) | ||
518 | // m_AgentRegions.Remove(agentID); | ||
519 | // } | ||
520 | |||
521 | /// <summary> | 450 | /// <summary> |
522 | /// | 451 | /// |
523 | /// </summary> | 452 | /// </summary> |
524 | /// <param name="msg"></param> | 453 | /// <param name="im"></param> |
525 | private void OnGridInstantMessage(GridInstantMessage msg) | 454 | private void OnGridInstantMessage(GridInstantMessage im) |
526 | { | 455 | { |
456 | // Check if it's a type of message that we should handle | ||
457 | if (!((im.dialog == (byte) InstantMessageDialog.InventoryOffered) | ||
458 | || (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered) | ||
459 | || (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) | ||
460 | || (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) | ||
461 | || (im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined))) | ||
462 | return; | ||
463 | |||
464 | m_log.DebugFormat( | ||
465 | "[INVENTORY TRANSFER]: {0} IM type received from grid. From={1} ({2}), To={3}", | ||
466 | (InstantMessageDialog)im.dialog, im.fromAgentID, im.fromAgentName, im.toAgentID); | ||
467 | |||
527 | // Check if this is ours to handle | 468 | // Check if this is ours to handle |
528 | // | 469 | // |
529 | Scene scene = FindClientScene(new UUID(msg.toAgentID)); | 470 | Scene scene = FindClientScene(new UUID(im.toAgentID)); |
530 | 471 | ||
531 | if (scene == null) | 472 | if (scene == null) |
532 | return; | 473 | return; |
533 | 474 | ||
534 | // Find agent to deliver to | 475 | // Find agent to deliver to |
535 | // | 476 | // |
536 | ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); | 477 | ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); |
537 | 478 | ||
538 | // Just forward to local handling | 479 | if (user != null) |
539 | OnInstantMessage(user.ControllingClient, msg); | 480 | { |
481 | user.ControllingClient.SendInstantMessage(im); | ||
482 | |||
483 | if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) | ||
484 | { | ||
485 | AssetType assetType = (AssetType)im.binaryBucket[0]; | ||
486 | UUID inventoryID = new UUID(im.binaryBucket, 1); | ||
487 | |||
488 | IInventoryService invService = scene.InventoryService; | ||
489 | InventoryNodeBase node = null; | ||
490 | if (AssetType.Folder == assetType) | ||
491 | { | ||
492 | InventoryFolderBase folder = new InventoryFolderBase(inventoryID, new UUID(im.toAgentID)); | ||
493 | node = invService.GetFolder(folder); | ||
494 | } | ||
495 | else | ||
496 | { | ||
497 | InventoryItemBase item = new InventoryItemBase(inventoryID, new UUID(im.toAgentID)); | ||
498 | node = invService.GetItem(item); | ||
499 | } | ||
540 | 500 | ||
501 | if (node != null) | ||
502 | user.ControllingClient.SendBulkUpdateInventory(node); | ||
503 | } | ||
504 | } | ||
541 | } | 505 | } |
542 | } | 506 | } |
543 | } | 507 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs new file mode 100644 index 0000000..7ddc396 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs | |||
@@ -0,0 +1,448 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net.Config; | ||
32 | using Nini.Config; | ||
33 | using NUnit.Framework; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.Assets; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.CoreModules.Avatar.Inventory.Transfer; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Tests.Common; | ||
42 | |||
43 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests | ||
44 | { | ||
45 | [TestFixture] | ||
46 | public class InventoryTransferModuleTests : OpenSimTestCase | ||
47 | { | ||
48 | protected TestScene m_scene; | ||
49 | |||
50 | [SetUp] | ||
51 | public override void SetUp() | ||
52 | { | ||
53 | base.SetUp(); | ||
54 | |||
55 | IConfigSource config = new IniConfigSource(); | ||
56 | config.AddConfig("Messaging"); | ||
57 | config.Configs["Messaging"].Set("InventoryTransferModule", "InventoryTransferModule"); | ||
58 | |||
59 | m_scene = new SceneHelpers().SetupScene(); | ||
60 | SceneHelpers.SetupSceneModules(m_scene, config, new InventoryTransferModule()); | ||
61 | } | ||
62 | |||
63 | [Test] | ||
64 | public void TestAcceptGivenItem() | ||
65 | { | ||
66 | // TestHelpers.EnableLogging(); | ||
67 | |||
68 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
69 | UUID itemId = TestHelpers.ParseTail(0x100); | ||
70 | UUID assetId = TestHelpers.ParseTail(0x200); | ||
71 | |||
72 | UserAccount ua1 | ||
73 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
74 | UserAccount ua2 | ||
75 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
76 | |||
77 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
78 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
79 | |||
80 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
81 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
82 | |||
83 | // Create the object to test give | ||
84 | InventoryItemBase originalItem | ||
85 | = UserInventoryHelpers.CreateInventoryItem( | ||
86 | m_scene, "givenObj", itemId, assetId, giverSp.UUID, InventoryType.Object); | ||
87 | |||
88 | byte[] giveImBinaryBucket = new byte[17]; | ||
89 | byte[] itemIdBytes = itemId.GetBytes(); | ||
90 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
91 | |||
92 | GridInstantMessage giveIm | ||
93 | = new GridInstantMessage( | ||
94 | m_scene, | ||
95 | giverSp.UUID, | ||
96 | giverSp.Name, | ||
97 | receiverSp.UUID, | ||
98 | (byte)InstantMessageDialog.InventoryOffered, | ||
99 | false, | ||
100 | "inventory offered msg", | ||
101 | initialSessionId, | ||
102 | false, | ||
103 | Vector3.Zero, | ||
104 | giveImBinaryBucket, | ||
105 | true); | ||
106 | |||
107 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
108 | |||
109 | // These details might not all be correct. | ||
110 | GridInstantMessage acceptIm | ||
111 | = new GridInstantMessage( | ||
112 | m_scene, | ||
113 | receiverSp.UUID, | ||
114 | receiverSp.Name, | ||
115 | giverSp.UUID, | ||
116 | (byte)InstantMessageDialog.InventoryAccepted, | ||
117 | false, | ||
118 | "inventory accepted msg", | ||
119 | initialSessionId, | ||
120 | false, | ||
121 | Vector3.Zero, | ||
122 | null, | ||
123 | true); | ||
124 | |||
125 | receiverClient.HandleImprovedInstantMessage(acceptIm); | ||
126 | |||
127 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
128 | // TODO: Test no-copy items. | ||
129 | InventoryItemBase originalItemAfterGive | ||
130 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
131 | |||
132 | Assert.That(originalItemAfterGive, Is.Not.Null); | ||
133 | Assert.That(originalItemAfterGive.ID, Is.EqualTo(originalItem.ID)); | ||
134 | |||
135 | // Test for item successfully making it into the receiver's inventory | ||
136 | InventoryItemBase receivedItem | ||
137 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Objects/givenObj"); | ||
138 | |||
139 | Assert.That(receivedItem, Is.Not.Null); | ||
140 | Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); | ||
141 | |||
142 | // Test that on a delete, item still exists and is accessible for the giver. | ||
143 | m_scene.InventoryService.DeleteItems(receiverSp.UUID, new List<UUID>() { receivedItem.ID }); | ||
144 | |||
145 | InventoryItemBase originalItemAfterDelete | ||
146 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
147 | |||
148 | Assert.That(originalItemAfterDelete, Is.Not.Null); | ||
149 | |||
150 | // TODO: Test scenario where giver deletes their item first. | ||
151 | } | ||
152 | |||
153 | /// <summary> | ||
154 | /// Test user rejection of a given item. | ||
155 | /// </summary> | ||
156 | /// <remarks> | ||
157 | /// A rejected item still ends up in the user's trash folder. | ||
158 | /// </remarks> | ||
159 | [Test] | ||
160 | public void TestRejectGivenItem() | ||
161 | { | ||
162 | // TestHelpers.EnableLogging(); | ||
163 | |||
164 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
165 | UUID itemId = TestHelpers.ParseTail(0x100); | ||
166 | UUID assetId = TestHelpers.ParseTail(0x200); | ||
167 | |||
168 | UserAccount ua1 | ||
169 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
170 | UserAccount ua2 | ||
171 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
172 | |||
173 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
174 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
175 | |||
176 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
177 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
178 | |||
179 | // Create the object to test give | ||
180 | InventoryItemBase originalItem | ||
181 | = UserInventoryHelpers.CreateInventoryItem( | ||
182 | m_scene, "givenObj", itemId, assetId, giverSp.UUID, InventoryType.Object); | ||
183 | |||
184 | GridInstantMessage receivedIm = null; | ||
185 | receiverClient.OnReceivedInstantMessage += im => receivedIm = im; | ||
186 | |||
187 | byte[] giveImBinaryBucket = new byte[17]; | ||
188 | byte[] itemIdBytes = itemId.GetBytes(); | ||
189 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
190 | |||
191 | GridInstantMessage giveIm | ||
192 | = new GridInstantMessage( | ||
193 | m_scene, | ||
194 | giverSp.UUID, | ||
195 | giverSp.Name, | ||
196 | receiverSp.UUID, | ||
197 | (byte)InstantMessageDialog.InventoryOffered, | ||
198 | false, | ||
199 | "inventory offered msg", | ||
200 | initialSessionId, | ||
201 | false, | ||
202 | Vector3.Zero, | ||
203 | giveImBinaryBucket, | ||
204 | true); | ||
205 | |||
206 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
207 | |||
208 | // These details might not all be correct. | ||
209 | // Session ID is now the created item ID (!) | ||
210 | GridInstantMessage rejectIm | ||
211 | = new GridInstantMessage( | ||
212 | m_scene, | ||
213 | receiverSp.UUID, | ||
214 | receiverSp.Name, | ||
215 | giverSp.UUID, | ||
216 | (byte)InstantMessageDialog.InventoryDeclined, | ||
217 | false, | ||
218 | "inventory declined msg", | ||
219 | new UUID(receivedIm.imSessionID), | ||
220 | false, | ||
221 | Vector3.Zero, | ||
222 | null, | ||
223 | true); | ||
224 | |||
225 | receiverClient.HandleImprovedInstantMessage(rejectIm); | ||
226 | |||
227 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
228 | // TODO: Test no-copy items. | ||
229 | InventoryItemBase originalItemAfterGive | ||
230 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
231 | |||
232 | Assert.That(originalItemAfterGive, Is.Not.Null); | ||
233 | Assert.That(originalItemAfterGive.ID, Is.EqualTo(originalItem.ID)); | ||
234 | |||
235 | // Test for item successfully making it into the receiver's inventory | ||
236 | InventoryItemBase receivedItem | ||
237 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Trash/givenObj"); | ||
238 | |||
239 | InventoryFolderBase trashFolder | ||
240 | = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, FolderType.Trash); | ||
241 | |||
242 | Assert.That(receivedItem, Is.Not.Null); | ||
243 | Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); | ||
244 | Assert.That(receivedItem.Folder, Is.EqualTo(trashFolder.ID)); | ||
245 | |||
246 | // Test that on a delete, item still exists and is accessible for the giver. | ||
247 | m_scene.InventoryService.PurgeFolder(trashFolder); | ||
248 | |||
249 | InventoryItemBase originalItemAfterDelete | ||
250 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
251 | |||
252 | Assert.That(originalItemAfterDelete, Is.Not.Null); | ||
253 | } | ||
254 | |||
255 | [Test] | ||
256 | public void TestAcceptGivenFolder() | ||
257 | { | ||
258 | TestHelpers.InMethod(); | ||
259 | // TestHelpers.EnableLogging(); | ||
260 | |||
261 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
262 | UUID folderId = TestHelpers.ParseTail(0x100); | ||
263 | |||
264 | UserAccount ua1 | ||
265 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
266 | UserAccount ua2 | ||
267 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
268 | |||
269 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
270 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
271 | |||
272 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
273 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
274 | |||
275 | InventoryFolderBase originalFolder | ||
276 | = UserInventoryHelpers.CreateInventoryFolder( | ||
277 | m_scene.InventoryService, giverSp.UUID, folderId, "f1", true); | ||
278 | |||
279 | byte[] giveImBinaryBucket = new byte[17]; | ||
280 | giveImBinaryBucket[0] = (byte)AssetType.Folder; | ||
281 | byte[] itemIdBytes = folderId.GetBytes(); | ||
282 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
283 | |||
284 | GridInstantMessage giveIm | ||
285 | = new GridInstantMessage( | ||
286 | m_scene, | ||
287 | giverSp.UUID, | ||
288 | giverSp.Name, | ||
289 | receiverSp.UUID, | ||
290 | (byte)InstantMessageDialog.InventoryOffered, | ||
291 | false, | ||
292 | "inventory offered msg", | ||
293 | initialSessionId, | ||
294 | false, | ||
295 | Vector3.Zero, | ||
296 | giveImBinaryBucket, | ||
297 | true); | ||
298 | |||
299 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
300 | |||
301 | // These details might not all be correct. | ||
302 | GridInstantMessage acceptIm | ||
303 | = new GridInstantMessage( | ||
304 | m_scene, | ||
305 | receiverSp.UUID, | ||
306 | receiverSp.Name, | ||
307 | giverSp.UUID, | ||
308 | (byte)InstantMessageDialog.InventoryAccepted, | ||
309 | false, | ||
310 | "inventory accepted msg", | ||
311 | initialSessionId, | ||
312 | false, | ||
313 | Vector3.Zero, | ||
314 | null, | ||
315 | true); | ||
316 | |||
317 | receiverClient.HandleImprovedInstantMessage(acceptIm); | ||
318 | |||
319 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
320 | // TODO: Test no-copy items. | ||
321 | InventoryFolderBase originalFolderAfterGive | ||
322 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
323 | |||
324 | Assert.That(originalFolderAfterGive, Is.Not.Null); | ||
325 | Assert.That(originalFolderAfterGive.ID, Is.EqualTo(originalFolder.ID)); | ||
326 | |||
327 | // Test for item successfully making it into the receiver's inventory | ||
328 | InventoryFolderBase receivedFolder | ||
329 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "f1"); | ||
330 | |||
331 | Assert.That(receivedFolder, Is.Not.Null); | ||
332 | Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID)); | ||
333 | |||
334 | // Test that on a delete, item still exists and is accessible for the giver. | ||
335 | m_scene.InventoryService.DeleteFolders(receiverSp.UUID, new List<UUID>() { receivedFolder.ID }); | ||
336 | |||
337 | InventoryFolderBase originalFolderAfterDelete | ||
338 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
339 | |||
340 | Assert.That(originalFolderAfterDelete, Is.Not.Null); | ||
341 | |||
342 | // TODO: Test scenario where giver deletes their item first. | ||
343 | } | ||
344 | |||
345 | /// <summary> | ||
346 | /// Test user rejection of a given item. | ||
347 | /// </summary> | ||
348 | /// <remarks> | ||
349 | /// A rejected item still ends up in the user's trash folder. | ||
350 | /// </remarks> | ||
351 | [Test] | ||
352 | public void TestRejectGivenFolder() | ||
353 | { | ||
354 | TestHelpers.InMethod(); | ||
355 | // TestHelpers.EnableLogging(); | ||
356 | |||
357 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
358 | UUID folderId = TestHelpers.ParseTail(0x100); | ||
359 | |||
360 | UserAccount ua1 | ||
361 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
362 | UserAccount ua2 | ||
363 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
364 | |||
365 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
366 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
367 | |||
368 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
369 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
370 | |||
371 | // Create the folder to test give | ||
372 | InventoryFolderBase originalFolder | ||
373 | = UserInventoryHelpers.CreateInventoryFolder( | ||
374 | m_scene.InventoryService, giverSp.UUID, folderId, "f1", true); | ||
375 | |||
376 | GridInstantMessage receivedIm = null; | ||
377 | receiverClient.OnReceivedInstantMessage += im => receivedIm = im; | ||
378 | |||
379 | byte[] giveImBinaryBucket = new byte[17]; | ||
380 | giveImBinaryBucket[0] = (byte)AssetType.Folder; | ||
381 | byte[] itemIdBytes = folderId.GetBytes(); | ||
382 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
383 | |||
384 | GridInstantMessage giveIm | ||
385 | = new GridInstantMessage( | ||
386 | m_scene, | ||
387 | giverSp.UUID, | ||
388 | giverSp.Name, | ||
389 | receiverSp.UUID, | ||
390 | (byte)InstantMessageDialog.InventoryOffered, | ||
391 | false, | ||
392 | "inventory offered msg", | ||
393 | initialSessionId, | ||
394 | false, | ||
395 | Vector3.Zero, | ||
396 | giveImBinaryBucket, | ||
397 | true); | ||
398 | |||
399 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
400 | |||
401 | // These details might not all be correct. | ||
402 | // Session ID is now the created item ID (!) | ||
403 | GridInstantMessage rejectIm | ||
404 | = new GridInstantMessage( | ||
405 | m_scene, | ||
406 | receiverSp.UUID, | ||
407 | receiverSp.Name, | ||
408 | giverSp.UUID, | ||
409 | (byte)InstantMessageDialog.InventoryDeclined, | ||
410 | false, | ||
411 | "inventory declined msg", | ||
412 | new UUID(receivedIm.imSessionID), | ||
413 | false, | ||
414 | Vector3.Zero, | ||
415 | null, | ||
416 | true); | ||
417 | |||
418 | receiverClient.HandleImprovedInstantMessage(rejectIm); | ||
419 | |||
420 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
421 | // TODO: Test no-copy items. | ||
422 | InventoryFolderBase originalFolderAfterGive | ||
423 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
424 | |||
425 | Assert.That(originalFolderAfterGive, Is.Not.Null); | ||
426 | Assert.That(originalFolderAfterGive.ID, Is.EqualTo(originalFolder.ID)); | ||
427 | |||
428 | // Test for folder successfully making it into the receiver's inventory | ||
429 | InventoryFolderBase receivedFolder | ||
430 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "Trash/f1"); | ||
431 | |||
432 | InventoryFolderBase trashFolder | ||
433 | = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, FolderType.Trash); | ||
434 | |||
435 | Assert.That(receivedFolder, Is.Not.Null); | ||
436 | Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID)); | ||
437 | Assert.That(receivedFolder.ParentID, Is.EqualTo(trashFolder.ID)); | ||
438 | |||
439 | // Test that on a delete, item still exists and is accessible for the giver. | ||
440 | m_scene.InventoryService.PurgeFolder(trashFolder); | ||
441 | |||
442 | InventoryFolderBase originalFolderAfterDelete | ||
443 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
444 | |||
445 | Assert.That(originalFolderAfterDelete, Is.Not.Null); | ||
446 | } | ||
447 | } | ||
448 | } \ No newline at end of file | ||