aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs122
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs85
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs8
4 files changed, 199 insertions, 136 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 4c02214..ee8b1bf 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -99,36 +99,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
99 int failedAssetRestores = 0; 99 int failedAssetRestores = 0;
100 int successfulItemRestores = 0; 100 int successfulItemRestores = 0;
101 List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); 101 List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>();
102
103 /*
104 if (!m_userInfo.HasReceivedInventory)
105 {
106 // If the region server has access to the user admin service (by which users are created),
107 // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
108 // server.
109 //
110 // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
111 // use a remote inventory service, though this is vanishingly rare at the moment.
112 if (null == m_scene.CommsManager.UserAdminService)
113 {
114 m_log.ErrorFormat(
115 "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
116 m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);
117
118 return nodesLoaded;
119 }
120 else
121 {
122 m_userInfo.FetchInventory();
123 for (int i = 0 ; i < 50 ; i++)
124 {
125 if (m_userInfo.HasReceivedInventory == true)
126 break;
127 Thread.Sleep(200);
128 }
129 }
130 }
131 */
132 102
133 //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); 103 //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath);
134 InventoryFolderBase rootDestinationFolder 104 InventoryFolderBase rootDestinationFolder
@@ -159,6 +129,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
159 successfulAssetRestores++; 129 successfulAssetRestores++;
160 else 130 else
161 failedAssetRestores++; 131 failedAssetRestores++;
132
133 if ((successfulAssetRestores) % 50 == 0)
134 m_log.DebugFormat(
135 "[INVENTORY ARCHIVER]: Loaded {0} assets...",
136 successfulAssetRestores);
162 } 137 }
163 else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) 138 else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
164 { 139 {
@@ -168,43 +143,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
168 rootDestinationFolder, foldersCreated, nodesLoaded); 143 rootDestinationFolder, foldersCreated, nodesLoaded);
169 144
170 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) 145 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
171 { 146 {
172 // Escape back characters 147 InventoryItemBase item = LoadItem(data, foundFolder);
173 filePath = filePath.Replace("&#47;", "/");
174 filePath = filePath.Replace("&amp;", "&");
175
176 InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);
177
178 // Don't use the item ID that's in the file
179 item.ID = UUID.Random();
180
181 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager);
182 if (UUID.Zero != ospResolvedId)
183 item.CreatorIdAsUuid = ospResolvedId;
184 else
185 item.CreatorIdAsUuid = m_userInfo.UserProfile.ID;
186
187 item.Owner = m_userInfo.UserProfile.ID;
188
189 // Reset folder ID to the one in which we want to load it
190 item.Folder = foundFolder.ID;
191
192 //m_userInfo.AddItem(item);
193 m_scene.InventoryService.AddItem(item);
194 successfulItemRestores++;
195 148
196 // If we're loading an item directly into the given destination folder then we need to record 149 if (item != null)
197 // it separately from any loaded root folders 150 {
198 if (rootDestinationFolder == foundFolder) 151 successfulItemRestores++;
199 nodesLoaded.Add(item); 152
153 // If we're loading an item directly into the given destination folder then we need to record
154 // it separately from any loaded root folders
155 if (rootDestinationFolder == foundFolder)
156 nodesLoaded.Add(item);
157 }
200 } 158 }
201 } 159 }
202 } 160 }
203 161
204 archive.Close(); 162 archive.Close();
205 163
206 m_log.DebugFormat("[INVENTORY ARCHIVER]: Restored {0} assets", successfulAssetRestores); 164 m_log.DebugFormat(
207 m_log.InfoFormat("[INVENTORY ARCHIVER]: Restored {0} items", successfulItemRestores); 165 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
166 successfulAssetRestores, failedAssetRestores);
167 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
208 168
209 return nodesLoaded; 169 return nodesLoaded;
210 } 170 }
@@ -239,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
239 string originalArchivePath = archivePath; 199 string originalArchivePath = archivePath;
240 200
241 m_log.DebugFormat( 201 m_log.DebugFormat(
242 "[INVENTORY ARCHIVER]: Loading to folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); 202 "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
243 203
244 InventoryFolderBase destFolder = null; 204 InventoryFolderBase destFolder = null;
245 205
@@ -250,8 +210,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
250 { 210 {
251 if (foldersCreated.ContainsKey(archivePath)) 211 if (foldersCreated.ContainsKey(archivePath))
252 { 212 {
253 m_log.DebugFormat( 213// m_log.DebugFormat(
254 "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); 214// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
255 destFolder = foldersCreated[archivePath]; 215 destFolder = foldersCreated[archivePath];
256 } 216 }
257 else 217 else
@@ -294,10 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
294 254
295 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); 255 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
296 256
297 // Escape back characters 257 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
298 newFolderName = newFolderName.Replace("&#47;", "/");
299 newFolderName = newFolderName.Replace("&amp;", "&");
300
301 UUID newFolderId = UUID.Random(); 258 UUID newFolderId = UUID.Random();
302 259
303 // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be 260 // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be
@@ -370,6 +327,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
370 } 327 }
371 328
372 /// <summary> 329 /// <summary>
330 /// Load an item from the archive
331 /// </summary>
332 /// <param name="filePath">The archive path for the item</param>
333 /// <param name="data">The raw item data</param>
334 /// <param name="rootDestinationFolder">The root destination folder for loaded items</param>
335 /// <param name="nodesLoaded">All the inventory nodes (items and folders) loaded so far</param>
336 protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder)
337 {
338 InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);
339
340 // Don't use the item ID that's in the file
341 item.ID = UUID.Random();
342
343 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager);
344 if (UUID.Zero != ospResolvedId)
345 item.CreatorIdAsUuid = ospResolvedId;
346 else
347 item.CreatorIdAsUuid = m_userInfo.UserProfile.ID;
348
349 item.Owner = m_userInfo.UserProfile.ID;
350
351 // Reset folder ID to the one in which we want to load it
352 item.Folder = loadFolder.ID;
353
354 //m_userInfo.AddItem(item);
355 m_scene.InventoryService.AddItem(item);
356
357 return item;
358 }
359
360 /// <summary>
373 /// Load an asset 361 /// Load an asset
374 /// </summary> 362 /// </summary>
375 /// <param name="assetFilename"></param> 363 /// <param name="assetFilename"></param>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index a822d10..247cee4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -27,6 +27,9 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
30using OpenMetaverse; 33using OpenMetaverse;
31using OpenSim.Framework; 34using OpenSim.Framework;
32using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
@@ -38,7 +41,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
38 /// </summary> 41 /// </summary>
39 public static class InventoryArchiveUtils 42 public static class InventoryArchiveUtils
40 { 43 {
41 public static readonly string PATH_DELIMITER = "/"; 44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings
47 public static readonly char ESCAPE_CHARACTER = '\\';
48
49 // The character used to separate inventory path components (different folders and items)
50 public static readonly char PATH_DELIMITER = '/';
42 51
43 /// <summary> 52 /// <summary>
44 /// 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
@@ -103,10 +112,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
103 112
104 path = path.Trim(); 113 path = path.Trim();
105 114
106 if (path == PATH_DELIMITER) 115 if (path == PATH_DELIMITER.ToString())
107 return startFolder; 116 return startFolder;
108 117
109 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 118 string[] components = SplitEscapedPath(path);
119 components[0] = UnescapePath(components[0]);
120
121 //string[] components = path.Split(new string[] { PATH_DELIMITER.ToString() }, 2, StringSplitOptions.None);
122
110 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 123 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
111 124
112 foreach (InventoryFolderBase folder in contents.Folders) 125 foreach (InventoryFolderBase folder in contents.Folders)
@@ -181,10 +194,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
181 public static InventoryItemBase FindItemByPath( 194 public static InventoryItemBase FindItemByPath(
182 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 195 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
183 { 196 {
184 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 197 string[] components = SplitEscapedPath(path);
198 components[0] = UnescapePath(components[0]);
199
200 //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
185 201
186 if (components.Length == 1) 202 if (components.Length == 1)
187 { 203 {
204// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]);
205
188 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 206 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
189 foreach (InventoryItemBase item in items) 207 foreach (InventoryItemBase item in items)
190 { 208 {
@@ -194,6 +212,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
194 } 212 }
195 else 213 else
196 { 214 {
215// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
216
197 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 217 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
198 218
199 foreach (InventoryFolderBase folder in contents.Folders) 219 foreach (InventoryFolderBase folder in contents.Folders)
@@ -206,5 +226,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 // We didn't find an item or intermediate folder with the given name 226 // We didn't find an item or intermediate folder with the given name
207 return null; 227 return null;
208 } 228 }
229
230 /// <summary>
231 /// Split a human escaped path into two components if it contains an unescaped path delimiter, or one component
232 /// if no delimiter is present
233 /// </summary>
234 /// <param name="path"></param>
235 /// <returns>
236 /// The split path. We leave the components in their originally unescaped state (though we remove the delimiter
237 /// which originally split them if applicable).
238 /// </returns>
239 public static string[] SplitEscapedPath(string path)
240 {
241// m_log.DebugFormat("SPLITTING PATH {0}", path);
242
243 bool singleEscapeChar = false;
244
245 for (int i = 0; i < path.Length; i++)
246 {
247 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
248 {
249 singleEscapeChar = true;
250 }
251 else
252 {
253 if (PATH_DELIMITER == path[i] && !singleEscapeChar)
254 return new string[2] { path.Remove(i), path.Substring(i + 1) };
255 else
256 singleEscapeChar = false;
257 }
258 }
259
260 // We didn't find a delimiter
261 return new string[1] { path };
262 }
263
264 /// <summary>
265 /// Unescapes a human escaped path. This means that "\\" goes to "\", and "\/" goes to "/"
266 /// </summary>
267 /// <param name="path"></param>
268 /// <returns></returns>
269 public static string UnescapePath(string path)
270 {
271// m_log.DebugFormat("ESCAPING PATH {0}", path);
272
273 StringBuilder sb = new StringBuilder();
274
275 bool singleEscapeChar = false;
276 for (int i = 0; i < path.Length; i++)
277 {
278 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
279 singleEscapeChar = true;
280 else
281 singleEscapeChar = false;
282
283 if (singleEscapeChar)
284 {
285 if (PATH_DELIMITER == path[i])
286 sb.Append(PATH_DELIMITER);
287 }
288 else
289 {
290 sb.Append(path[i]);
291 }
292 }
293
294// m_log.DebugFormat("ESCAPED PATH TO {0}", sb);
295
296 return sb.ToString();
297 }
298
299 /// <summary>
300 /// Escape an archive path.
301 /// </summary>
302 /// This has to be done differently from human paths because we can't leave in any "/" characters (due to
303 /// problems if the archive is built from or extracted to a filesystem
304 /// <param name="path"></param>
305 /// <returns></returns>
306 public static string EscapeArchivePath(string path)
307 {
308 // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
309 return path.Replace("&", "&amp;").Replace("/", "&#47;");
310 }
311
312 /// <summary>
313 /// Unescape an archive path.
314 /// </summary>
315 /// <param name="path"></param>
316 /// <returns></returns>
317 public static string UnescapeArchivePath(string path)
318 {
319 return path.Replace("&#47;", "/").Replace("&amp;", "&");
320 }
209 } 321 }
210} \ No newline at end of file 322} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index af0b72f..bbb49f6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -217,37 +217,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
217 InventoryItemBase inventoryItem = null; 217 InventoryItemBase inventoryItem = null;
218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID); 218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID);
219 219
220 // XXX: Very temporarily, drop and refetch inventory to make sure we have any newly created items in cache
221 // This will disappear very soon once we stop using the old cached inventory.
222 /*
223 m_userInfo.DropInventory();
224 m_userInfo.FetchInventory();
225 */
226
227 /*
228 if (!m_userInfo.HasReceivedInventory)
229 {
230 // If the region server has access to the user admin service (by which users are created),
231 // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
232 // server.
233 //
234 // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
235 // use a remote inventory service, though this is vanishingly rare at the moment.
236 if (null == m_scene.CommsManager.UserAdminService)
237 {
238 m_log.ErrorFormat(
239 "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
240 m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);
241
242 return;
243 }
244 else
245 {
246 m_userInfo.FetchInventory();
247 }
248 }
249 */
250
251 bool foundStar = false; 220 bool foundStar = false;
252 221
253 // Eliminate double slashes and any leading / on the path. 222 // Eliminate double slashes and any leading / on the path.
@@ -294,34 +263,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
294 263
295 m_archiveWriter = new TarArchiveWriter(m_saveStream); 264 m_archiveWriter = new TarArchiveWriter(m_saveStream);
296 265
297 if (null == inventoryFolder) 266 if (inventoryFolder != null)
298 {
299 if (null == inventoryItem)
300 {
301 // We couldn't find the path indicated
302 m_saveStream.Close();
303 m_module.TriggerInventoryArchiveSaved(
304 m_id, false, m_userInfo, m_invPath, m_saveStream,
305 new Exception(string.Format("Could not find inventory entry at path {0}", m_invPath)));
306 return;
307 }
308 else
309 {
310 m_log.DebugFormat(
311 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
312 inventoryItem.Name, inventoryItem.ID, m_invPath);
313
314 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
315 }
316 }
317 else
318 { 267 {
319 m_log.DebugFormat( 268 m_log.DebugFormat(
320 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", 269 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
321 inventoryFolder.Name, inventoryFolder.ID, m_invPath); 270 inventoryFolder.Name, inventoryFolder.ID, m_invPath);
322 271
323 //recurse through all dirs getting dirs and files 272 //recurse through all dirs getting dirs and files
324 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); 273 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar);
274 }
275 else if (inventoryItem != null)
276 {
277 m_log.DebugFormat(
278 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
279 inventoryItem.Name, inventoryItem.ID, m_invPath);
280
281 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
282 }
283 else
284 {
285 // We couldn't find the path indicated
286 m_saveStream.Close();
287 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
288 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage);
289 m_module.TriggerInventoryArchiveSaved(
290 m_id, false, m_userInfo, m_invPath, m_saveStream,
291 new Exception(errorMessage));
292 return;
325 } 293 }
326 294
327 // Don't put all this profile information into the archive right now. 295 // Don't put all this profile information into the archive right now.
@@ -394,13 +362,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
394 /// <returns></returns> 362 /// <returns></returns>
395 public static string CreateArchiveFolderName(string name, UUID id) 363 public static string CreateArchiveFolderName(string name, UUID id)
396 { 364 {
397 // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
398 name = name.Replace("&", "&amp;");
399 name = name.Replace("/", "&#47;");
400
401 return string.Format( 365 return string.Format(
402 "{0}{1}{2}/", 366 "{0}{1}{2}/",
403 name, 367 InventoryArchiveUtils.EscapeArchivePath(name),
404 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, 368 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
405 id); 369 id);
406 } 370 }
@@ -413,12 +377,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
413 /// <returns></returns> 377 /// <returns></returns>
414 public static string CreateArchiveItemName(string name, UUID id) 378 public static string CreateArchiveItemName(string name, UUID id)
415 { 379 {
416 name = name.Replace("&", "&amp;");
417 name = name.Replace("/", "&#47;");
418
419 return string.Format( 380 return string.Format(
420 "{0}{1}{2}.xml", 381 "{0}{1}{2}.xml",
421 name, 382 InventoryArchiveUtils.EscapeArchivePath(name),
422 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, 383 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
423 id); 384 id);
424 } 385 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index e300eb1..99d02c4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -295,7 +295,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
295 TestHelper.InMethod(); 295 TestHelper.InMethod();
296 log4net.Config.XmlConfigurator.Configure(); 296 log4net.Config.XmlConfigurator.Configure();
297 297
298 string itemName = "You & you are a mean man"; 298 string itemName = "You & you are a mean/man/";
299 string humanEscapedItemName = @"You & you are a mean\/man\/";
299 string userPassword = "meowfood"; 300 string userPassword = "meowfood";
300 301
301 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); 302 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
@@ -360,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
360 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); 361 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
361 mre.WaitOne(60000, false); 362 mre.WaitOne(60000, false);
362 363
363 /// LOAD ITEM 364 // LOAD ITEM
364 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 365 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
365 366
366 archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); 367 archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
@@ -369,7 +370,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
369 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); 370 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
370 371
371 InventoryItemBase foundItem1 372 InventoryItemBase foundItem1
372 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userId, "Scripts/Objects/" + itemName); 373 = InventoryArchiveUtils.FindItemByPath(
374 scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName);
373 375
374 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); 376 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
375// Assert.That( 377// Assert.That(