aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Inventory
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/CoreModules/Avatar/Inventory
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Inventory')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs155
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs86
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs106
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs (renamed from OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs)179
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs192
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs (renamed from OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs)275
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs166
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs448
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;
34using log4net; 34using log4net;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Monitoring;
37using OpenSim.Framework.Serialization; 38using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 39using OpenSim.Framework.Serialization.External;
39using OpenSim.Region.CoreModules.World.Archiver; 40using OpenSim.Region.CoreModules.World.Archiver;
@@ -42,6 +43,8 @@ using OpenSim.Services.Interfaces;
42using Ionic.Zlib; 43using Ionic.Zlib;
43using GZipStream = Ionic.Zlib.GZipStream; 44using GZipStream = Ionic.Zlib.GZipStream;
44using CompressionMode = Ionic.Zlib.CompressionMode; 45using CompressionMode = Ionic.Zlib.CompressionMode;
46using CompressionLevel = Ionic.Zlib.CompressionLevel;
47using PermissionMask = OpenSim.Framework.PermissionMask;
45 48
46namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 49namespace 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;
34using Nini.Config; 34using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Communications;
38using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
39using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 39using 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;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; 39using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
41using OpenSim.Region.CoreModules.World.Serialiser; 40using OpenSim.Region.CoreModules.World.Serialiser;
42using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 45
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 46namespace 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
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Threading;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Data;
36using OpenSim.Framework;
37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External;
39using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
40using OpenSim.Region.CoreModules.World.Serialiser;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Services.Interfaces;
44using OpenSim.Tests.Common;
45
46namespace 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;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; 39using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
41using OpenSim.Region.CoreModules.World.Serialiser; 40using OpenSim.Region.CoreModules.World.Serialiser;
42using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 45
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 46namespace 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;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; 39using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
41using OpenSim.Region.CoreModules.World.Serialiser; 40using OpenSim.Region.CoreModules.World.Serialiser;
42using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 45
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 46namespace 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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net.Config;
32using Nini.Config;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenMetaverse.Assets;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.Avatar.Inventory.Transfer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Tests.Common;
42
43namespace 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