diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | 297 |
1 files changed, 168 insertions, 129 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 4a06fd1..1e21b74 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -56,7 +56,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
56 | /// bumps here should be compatible. | 56 | /// bumps here should be compatible. |
57 | /// </summary> | 57 | /// </summary> |
58 | public static int MAX_MAJOR_VERSION = 1; | 58 | public static int MAX_MAJOR_VERSION = 1; |
59 | 59 | ||
60 | protected TarArchiveReader archive; | 60 | protected TarArchiveReader archive; |
61 | 61 | ||
62 | private UserAccount m_userInfo; | 62 | private UserAccount m_userInfo; |
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
66 | /// ID of this request | 66 | /// ID of this request |
67 | /// </value> | 67 | /// </value> |
68 | protected UUID m_id; | 68 | protected UUID m_id; |
69 | 69 | ||
70 | /// <summary> | 70 | /// <summary> |
71 | /// Do we want to merge this load with existing inventory? | 71 | /// Do we want to merge this load with existing inventory? |
72 | /// </summary> | 72 | /// </summary> |
@@ -82,46 +82,49 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
82 | /// The stream from which the inventory archive will be loaded. | 82 | /// The stream from which the inventory archive will be loaded. |
83 | /// </value> | 83 | /// </value> |
84 | private Stream m_loadStream; | 84 | private Stream m_loadStream; |
85 | 85 | ||
86 | /// <summary> | 86 | /// <summary> |
87 | /// Has the control file been loaded for this archive? | 87 | /// Has the control file been loaded for this archive? |
88 | /// </summary> | 88 | /// </summary> |
89 | public bool ControlFileLoaded { get; private set; } | 89 | public bool ControlFileLoaded { get; private set; } |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Do we want to enforce the check. IAR versions before 0.2 and 1.1 do not guarantee this order, so we can't | 92 | /// Do we want to enforce the check. IAR versions before 0.2 and 1.1 do not guarantee this order, so we can't |
93 | /// enforce. | 93 | /// enforce. |
94 | /// </summary> | 94 | /// </summary> |
95 | public bool EnforceControlFileCheck { get; private set; } | 95 | public bool EnforceControlFileCheck { get; private set; } |
96 | 96 | ||
97 | protected bool m_assetsLoaded; | 97 | protected bool m_assetsLoaded; |
98 | protected bool m_inventoryNodesLoaded; | 98 | protected bool m_inventoryNodesLoaded; |
99 | 99 | ||
100 | protected int m_successfulAssetRestores; | 100 | protected int m_successfulAssetRestores; |
101 | protected int m_failedAssetRestores; | 101 | protected int m_failedAssetRestores; |
102 | protected int m_successfulItemRestores; | 102 | protected int m_successfulItemRestores; |
103 | 103 | ||
104 | /// <summary> | 104 | /// <summary> |
105 | /// Root destination folder for the IAR load. | 105 | /// Root destination folder for the IAR load. |
106 | /// </summary> | 106 | /// </summary> |
107 | protected InventoryFolderBase m_rootDestinationFolder; | 107 | protected InventoryFolderBase m_rootDestinationFolder; |
108 | 108 | ||
109 | /// <summary> | 109 | /// <summary> |
110 | /// Inventory nodes loaded from the iar. | 110 | /// Inventory nodes loaded from the iar. |
111 | /// </summary> | 111 | /// </summary> |
112 | protected HashSet<InventoryNodeBase> m_loadedNodes = new HashSet<InventoryNodeBase>(); | 112 | protected Dictionary<UUID, InventoryNodeBase> m_loadedNodes = new Dictionary<UUID, InventoryNodeBase>(); |
113 | 113 | ||
114 | /// <summary> | 114 | /// <summary> |
115 | /// In order to load identically named folders, we need to keep track of the folders that we have already | 115 | /// In order to load identically named folders, we need to keep track of the folders that we have already |
116 | /// resolved. | 116 | /// resolved. |
117 | /// </summary> | 117 | /// </summary> |
118 | Dictionary <string, InventoryFolderBase> m_resolvedFolders = new Dictionary<string, InventoryFolderBase>(); | 118 | Dictionary <string, InventoryFolderBase> m_resolvedFolders = new Dictionary<string, InventoryFolderBase>(); |
119 | 119 | ||
120 | /// <summary> | 120 | /// <summary> |
121 | /// 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 |
122 | /// 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 |
123 | /// </summary> | 123 | /// </summary> |
124 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); | 124 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); |
125 | protected Dictionary<UUID, UUID> m_itemIDs = new Dictionary<UUID, UUID>(); | ||
126 | protected List<InventoryItemBase> m_invLinks = new List<InventoryItemBase>(); | ||
127 | protected Dictionary<UUID, InventoryNodeBase> m_invLinksFolders = new Dictionary<UUID, InventoryNodeBase>(); | ||
125 | 128 | ||
126 | public InventoryArchiveReadRequest( | 129 | public InventoryArchiveReadRequest( |
127 | IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) | 130 | IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) |
@@ -163,9 +166,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
163 | m_invPath = invPath; | 166 | m_invPath = invPath; |
164 | m_loadStream = loadStream; | 167 | m_loadStream = loadStream; |
165 | m_module = module; | 168 | m_module = module; |
166 | 169 | ||
167 | // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things | 170 | // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things |
168 | // (I thought they weren't). We will need to bump the version number and perform this check on all | 171 | // (I thought they weren't). We will need to bump the version number and perform this check on all |
169 | // subsequent IAR versions only | 172 | // subsequent IAR versions only |
170 | ControlFileLoaded = true; | 173 | ControlFileLoaded = true; |
171 | } | 174 | } |
@@ -181,26 +184,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
181 | /// returned | 184 | /// returned |
182 | /// </returns> | 185 | /// </returns> |
183 | /// <exception cref="System.Exception">Thrown if load fails.</exception> | 186 | /// <exception cref="System.Exception">Thrown if load fails.</exception> |
184 | public HashSet<InventoryNodeBase> Execute() | 187 | public Dictionary<UUID,InventoryNodeBase> Execute() |
185 | { | 188 | { |
186 | try | 189 | try |
187 | { | 190 | { |
188 | Exception reportedException = null; | 191 | Exception reportedException = null; |
189 | 192 | ||
190 | string filePath = "ERROR"; | 193 | string filePath = "ERROR"; |
191 | 194 | ||
192 | List<InventoryFolderBase> folderCandidates | 195 | List<InventoryFolderBase> folderCandidates |
193 | = InventoryArchiveUtils.FindFoldersByPath( | 196 | = InventoryArchiveUtils.FindFoldersByPath( |
194 | m_InventoryService, m_userInfo.PrincipalID, m_invPath); | 197 | m_InventoryService, m_userInfo.PrincipalID, m_invPath); |
195 | 198 | ||
196 | if (folderCandidates.Count == 0) | 199 | if (folderCandidates.Count == 0) |
197 | { | 200 | { |
198 | // Possibly provide an option later on to automatically create this folder if it does not exist | 201 | // Possibly provide an option later on to automatically create this folder if it does not exist |
199 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); | 202 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); |
200 | 203 | ||
201 | return m_loadedNodes; | 204 | return m_loadedNodes; |
202 | } | 205 | } |
203 | 206 | ||
204 | m_rootDestinationFolder = folderCandidates[0]; | 207 | m_rootDestinationFolder = folderCandidates[0]; |
205 | archive = new TarArchiveReader(m_loadStream); | 208 | archive = new TarArchiveReader(m_loadStream); |
206 | byte[] data; | 209 | byte[] data; |
@@ -211,7 +214,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
211 | if (filePath == ArchiveConstants.CONTROL_FILE_PATH) | 214 | if (filePath == ArchiveConstants.CONTROL_FILE_PATH) |
212 | { | 215 | { |
213 | LoadControlFile(filePath, data); | 216 | LoadControlFile(filePath, data); |
214 | } | 217 | } |
215 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) | 218 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) |
216 | { | 219 | { |
217 | LoadAssetFile(filePath, data); | 220 | LoadAssetFile(filePath, data); |
@@ -221,17 +224,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
221 | LoadInventoryFile(filePath, entryType, data); | 224 | LoadInventoryFile(filePath, entryType, data); |
222 | } | 225 | } |
223 | } | 226 | } |
224 | 227 | ||
225 | archive.Close(); | 228 | archive.Close(); |
229 | LoadInventoryLinks(); | ||
226 | 230 | ||
227 | m_log.DebugFormat( | 231 | m_log.DebugFormat( |
228 | "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", | 232 | "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", |
229 | m_successfulAssetRestores, m_failedAssetRestores); | 233 | m_successfulAssetRestores, m_failedAssetRestores); |
230 | 234 | ||
231 | //Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required | 235 | //Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required |
232 | if(m_module != null) | 236 | if(m_module != null) |
233 | m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores); | 237 | m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores); |
234 | 238 | ||
235 | return m_loadedNodes; | 239 | return m_loadedNodes; |
236 | } | 240 | } |
237 | catch(Exception Ex) | 241 | catch(Exception Ex) |
@@ -268,36 +272,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
268 | /// </param> | 272 | /// </param> |
269 | /// <returns>The last user inventory folder created or found for the archive path</returns> | 273 | /// <returns>The last user inventory folder created or found for the archive path</returns> |
270 | public InventoryFolderBase ReplicateArchivePathToUserInventory( | 274 | public InventoryFolderBase ReplicateArchivePathToUserInventory( |
271 | string iarPath, | 275 | string iarPath, |
272 | InventoryFolderBase rootDestFolder, | 276 | InventoryFolderBase rootDestFolder, |
273 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 277 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
274 | HashSet<InventoryNodeBase> loadedNodes) | 278 | Dictionary<UUID, InventoryNodeBase> loadedNodes) |
275 | { | 279 | { |
276 | string iarPathExisting = iarPath; | 280 | string iarPathExisting = iarPath; |
277 | 281 | ||
278 | // m_log.DebugFormat( | 282 | // m_log.DebugFormat( |
279 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); | 283 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); |
280 | 284 | ||
281 | InventoryFolderBase destFolder | 285 | InventoryFolderBase destFolder |
282 | = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); | 286 | = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); |
283 | 287 | ||
284 | // m_log.DebugFormat( | 288 | // m_log.DebugFormat( |
285 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", | 289 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", |
286 | // iarPath, iarPathExisting); | 290 | // iarPath, iarPathExisting); |
287 | 291 | ||
288 | string iarPathToCreate = iarPath.Substring(iarPathExisting.Length); | 292 | string iarPathToCreate = iarPath.Substring(iarPathExisting.Length); |
289 | CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes); | 293 | CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes); |
290 | 294 | ||
291 | return destFolder; | 295 | return destFolder; |
292 | } | 296 | } |
293 | 297 | ||
294 | /// <summary> | 298 | /// <summary> |
295 | /// Resolve a destination folder | 299 | /// Resolve a destination folder |
296 | /// </summary> | 300 | /// </summary> |
297 | /// | 301 | /// |
298 | /// We require here a root destination folder (usually the root of the user's inventory) and the archive | 302 | /// We require here a root destination folder (usually the root of the user's inventory) and the archive |
299 | /// path. We also pass in a list of previously resolved folders in case we've found this one previously. | 303 | /// path. We also pass in a list of previously resolved folders in case we've found this one previously. |
300 | /// | 304 | /// |
301 | /// <param name="archivePath"> | 305 | /// <param name="archivePath"> |
302 | /// The item archive path to resolve. The portion of the path passed back is that | 306 | /// The item archive path to resolve. The portion of the path passed back is that |
303 | /// which corresponds to the resolved desintation folder. | 307 | /// which corresponds to the resolved desintation folder. |
@@ -321,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
321 | while (archivePath.Length > 0) | 325 | while (archivePath.Length > 0) |
322 | { | 326 | { |
323 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); | 327 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); |
324 | 328 | ||
325 | if (resolvedFolders.ContainsKey(archivePath)) | 329 | if (resolvedFolders.ContainsKey(archivePath)) |
326 | { | 330 | { |
327 | // m_log.DebugFormat( | 331 | // m_log.DebugFormat( |
@@ -332,13 +336,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
332 | { | 336 | { |
333 | if (m_merge) | 337 | if (m_merge) |
334 | { | 338 | { |
335 | // TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the | 339 | // TODO: Using m_invPath is totally wrong - what we need to do is strip the uuid from the |
336 | // iar name and try to find that instead. | 340 | // iar name and try to find that instead. |
337 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | 341 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); |
338 | List<InventoryFolderBase> folderCandidates | 342 | List<InventoryFolderBase> folderCandidates |
339 | = InventoryArchiveUtils.FindFoldersByPath( | 343 | = InventoryArchiveUtils.FindFoldersByPath( |
340 | m_InventoryService, m_userInfo.PrincipalID, plainPath); | 344 | m_InventoryService, m_userInfo.PrincipalID, plainPath); |
341 | 345 | ||
342 | if (folderCandidates.Count != 0) | 346 | if (folderCandidates.Count != 0) |
343 | { | 347 | { |
344 | InventoryFolderBase destFolder = folderCandidates[0]; | 348 | InventoryFolderBase destFolder = folderCandidates[0]; |
@@ -346,7 +350,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
346 | return destFolder; | 350 | return destFolder; |
347 | } | 351 | } |
348 | } | 352 | } |
349 | 353 | ||
350 | // Don't include the last slash so find the penultimate one | 354 | // Don't include the last slash so find the penultimate one |
351 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | 355 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); |
352 | 356 | ||
@@ -365,10 +369,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
365 | } | 369 | } |
366 | } | 370 | } |
367 | } | 371 | } |
368 | 372 | ||
369 | return rootDestFolder; | 373 | return rootDestFolder; |
370 | } | 374 | } |
371 | 375 | ||
372 | /// <summary> | 376 | /// <summary> |
373 | /// Create a set of folders for the given path. | 377 | /// Create a set of folders for the given path. |
374 | /// </summary> | 378 | /// </summary> |
@@ -388,11 +392,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
388 | /// Track the inventory nodes created. | 392 | /// Track the inventory nodes created. |
389 | /// </param> | 393 | /// </param> |
390 | protected void CreateFoldersForPath( | 394 | protected void CreateFoldersForPath( |
391 | InventoryFolderBase destFolder, | 395 | InventoryFolderBase destFolder, |
392 | string iarPathExisting, | 396 | string iarPathExisting, |
393 | string iarPathToReplicate, | 397 | string iarPathToReplicate, |
394 | Dictionary <string, InventoryFolderBase> resolvedFolders, | 398 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
395 | HashSet<InventoryNodeBase> loadedNodes) | 399 | Dictionary<UUID, InventoryNodeBase> loadedNodes) |
396 | { | 400 | { |
397 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | 401 | string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); |
398 | 402 | ||
@@ -402,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
402 | 406 | ||
403 | if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR)) | 407 | if (!rawDirsToCreate[i].Contains(ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR)) |
404 | continue; | 408 | continue; |
405 | 409 | ||
406 | int identicalNameIdentifierIndex | 410 | int identicalNameIdentifierIndex |
407 | = rawDirsToCreate[i].LastIndexOf( | 411 | = rawDirsToCreate[i].LastIndexOf( |
408 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); | 412 | ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); |
@@ -412,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
412 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); | 416 | newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName); |
413 | UUID newFolderId = UUID.Random(); | 417 | UUID newFolderId = UUID.Random(); |
414 | 418 | ||
415 | destFolder | 419 | destFolder |
416 | = new InventoryFolderBase( | 420 | = new InventoryFolderBase( |
417 | newFolderId, newFolderName, m_userInfo.PrincipalID, | 421 | newFolderId, newFolderName, m_userInfo.PrincipalID, |
418 | (short)FolderType.None, destFolder.ID, 1); | 422 | (short)FolderType.None, destFolder.ID, 1); |
@@ -424,10 +428,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
424 | resolvedFolders[iarPathExisting] = destFolder; | 428 | resolvedFolders[iarPathExisting] = destFolder; |
425 | 429 | ||
426 | if (0 == i) | 430 | if (0 == i) |
427 | loadedNodes.Add(destFolder); | 431 | loadedNodes[destFolder.ID] = destFolder; |
428 | } | 432 | } |
429 | } | 433 | } |
430 | 434 | ||
431 | /// <summary> | 435 | /// <summary> |
432 | /// Load an item from the archive | 436 | /// Load an item from the archive |
433 | /// </summary> | 437 | /// </summary> |
@@ -438,15 +442,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
438 | protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) | 442 | protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder) |
439 | { | 443 | { |
440 | InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); | 444 | InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); |
441 | 445 | ||
446 | UUID oldID = item.ID; | ||
442 | // Don't use the item ID that's in the file | 447 | // Don't use the item ID that's in the file |
443 | item.ID = UUID.Random(); | 448 | item.ID = UUID.Random(); |
449 | m_itemIDs[oldID] = item.ID; | ||
444 | 450 | ||
445 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); | 451 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); |
446 | if (UUID.Zero != ospResolvedId) // The user exists in this grid | 452 | if (UUID.Zero != ospResolvedId) // The user exists in this grid |
447 | { | 453 | { |
448 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); | 454 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); |
449 | 455 | ||
450 | // item.CreatorIdAsUuid = ospResolvedId; | 456 | // item.CreatorIdAsUuid = ospResolvedId; |
451 | 457 | ||
452 | // Don't preserve the OSPA in the creator id (which actually gets persisted to the | 458 | // Don't preserve the OSPA in the creator id (which actually gets persisted to the |
@@ -457,7 +463,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
457 | else if (string.IsNullOrEmpty(item.CreatorData)) | 463 | else if (string.IsNullOrEmpty(item.CreatorData)) |
458 | { | 464 | { |
459 | item.CreatorId = m_userInfo.PrincipalID.ToString(); | 465 | item.CreatorId = m_userInfo.PrincipalID.ToString(); |
460 | // item.CreatorIdAsUuid = new UUID(item.CreatorId); | ||
461 | } | 466 | } |
462 | 467 | ||
463 | item.Owner = m_userInfo.PrincipalID; | 468 | item.Owner = m_userInfo.PrincipalID; |
@@ -470,11 +475,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
470 | // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger | 475 | // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger |
471 | // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than | 476 | // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than |
472 | // relying on native tar tools. | 477 | // relying on native tar tools. |
473 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; | 478 | if(item.AssetType == (int)AssetType.Link) |
479 | { | ||
480 | m_invLinks.Add(item); | ||
481 | if(!m_loadedNodes.ContainsKey(item.Folder) && !m_invLinksFolders.ContainsKey(item.Folder)) | ||
482 | m_invLinksFolders[item.Folder] = loadFolder; | ||
483 | return null; | ||
484 | } | ||
485 | else | ||
486 | { | ||
487 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; | ||
488 | if (!m_InventoryService.AddItem(item)) | ||
489 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); | ||
490 | } | ||
474 | 491 | ||
475 | if (!m_InventoryService.AddItem(item)) | ||
476 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); | ||
477 | |||
478 | return item; | 492 | return item; |
479 | } | 493 | } |
480 | 494 | ||
@@ -504,56 +518,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
504 | string rawUuid = filename.Remove(filename.Length - extension.Length); | 518 | string rawUuid = filename.Remove(filename.Length - extension.Length); |
505 | UUID assetId = new UUID(rawUuid); | 519 | UUID assetId = new UUID(rawUuid); |
506 | 520 | ||
507 | if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) | 521 | if (!ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) |
508 | { | 522 | { |
509 | sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; | 523 | m_log.ErrorFormat( |
524 | "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", | ||
525 | assetPath, extension); | ||
526 | return false; | ||
527 | } | ||
510 | 528 | ||
511 | if (assetType == (sbyte)AssetType.Unknown) | 529 | sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; |
512 | { | 530 | if (assetType == (sbyte)AssetType.Unknown) |
513 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); | 531 | { |
514 | } | 532 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); |
515 | else if (assetType == (sbyte)AssetType.Object) | 533 | return false; |
516 | { | 534 | } |
517 | if (m_creatorIdForAssetId.ContainsKey(assetId)) | 535 | |
536 | if(assetType == (sbyte)AssetType.Object) | ||
537 | { | ||
538 | UUID owner = m_userInfo.PrincipalID; | ||
539 | bool doCreatorID = m_creatorIdForAssetId.ContainsKey(assetId); | ||
540 | |||
541 | data = SceneObjectSerializer.ModifySerializedObject(assetId, data, | ||
542 | sog => | ||
518 | { | 543 | { |
519 | data = SceneObjectSerializer.ModifySerializedObject(assetId, data, | 544 | foreach(SceneObjectPart sop in sog.Parts) |
520 | sog => { | 545 | { |
521 | bool modified = false; | 546 | sop.OwnerID = owner; |
522 | 547 | if(doCreatorID && string.IsNullOrEmpty(sop.CreatorData)) | |
523 | foreach (SceneObjectPart sop in sog.Parts) | 548 | sop.CreatorID = m_creatorIdForAssetId[assetId]; |
524 | { | 549 | |
525 | if (string.IsNullOrEmpty(sop.CreatorData)) | 550 | foreach(TaskInventoryItem it in sop.Inventory.GetInventoryItems()) |
526 | { | 551 | { |
527 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | 552 | it.OwnerID = owner; |
528 | modified = true; | 553 | if(string.IsNullOrEmpty(it.CreatorData) && m_creatorIdForAssetId.ContainsKey(it.AssetID)) |
529 | } | 554 | it.CreatorID = m_creatorIdForAssetId[it.AssetID]; |
530 | } | 555 | } |
531 | 556 | } | |
532 | return modified; | 557 | return true; |
533 | }); | 558 | }); |
534 | |||
535 | if (data == null) | ||
536 | return false; | ||
537 | } | ||
538 | } | ||
539 | 559 | ||
540 | //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); | 560 | if(data == null) |
561 | return false; | ||
562 | } | ||
541 | 563 | ||
542 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); | 564 | //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); |
543 | asset.Data = data; | ||
544 | 565 | ||
545 | m_AssetService.Store(asset); | 566 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); |
567 | asset.Data = data; | ||
546 | 568 | ||
547 | return true; | 569 | m_AssetService.Store(asset); |
548 | } | ||
549 | else | ||
550 | { | ||
551 | m_log.ErrorFormat( | ||
552 | "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", | ||
553 | assetPath, extension); | ||
554 | 570 | ||
555 | return false; | 571 | return true; |
556 | } | ||
557 | } | 572 | } |
558 | 573 | ||
559 | /// <summary> | 574 | /// <summary> |
@@ -568,7 +583,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
568 | int majorVersion = int.Parse(archiveElement.Attribute("major_version").Value); | 583 | int majorVersion = int.Parse(archiveElement.Attribute("major_version").Value); |
569 | int minorVersion = int.Parse(archiveElement.Attribute("minor_version").Value); | 584 | int minorVersion = int.Parse(archiveElement.Attribute("minor_version").Value); |
570 | string version = string.Format("{0}.{1}", majorVersion, minorVersion); | 585 | string version = string.Format("{0}.{1}", majorVersion, minorVersion); |
571 | 586 | ||
572 | if (majorVersion > MAX_MAJOR_VERSION) | 587 | if (majorVersion > MAX_MAJOR_VERSION) |
573 | { | 588 | { |
574 | throw new Exception( | 589 | throw new Exception( |
@@ -576,38 +591,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
576 | "The IAR you are trying to load has major version number of {0} but this version of OpenSim can only load IARs with major version number {1} and below", | 591 | "The IAR you are trying to load has major version number of {0} but this version of OpenSim can only load IARs with major version number {1} and below", |
577 | majorVersion, MAX_MAJOR_VERSION)); | 592 | majorVersion, MAX_MAJOR_VERSION)); |
578 | } | 593 | } |
579 | 594 | ||
580 | ControlFileLoaded = true; | 595 | ControlFileLoaded = true; |
581 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); | 596 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); |
582 | } | 597 | } |
583 | 598 | ||
584 | /// <summary> | 599 | /// <summary> |
585 | /// Load inventory file | 600 | /// Load inventory file |
586 | /// </summary> | 601 | /// </summary> |
587 | /// <param name="path"></param> | 602 | /// <param name="path"></param> |
588 | /// <param name="entryType"></param> | 603 | /// <param name="entryType"></param> |
589 | /// <param name="data"></param> | 604 | /// <param name="data"></param> |
590 | protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data) | 605 | protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data) |
591 | { | 606 | { |
592 | if (!ControlFileLoaded) | 607 | if (!ControlFileLoaded) |
593 | throw new Exception( | 608 | throw new Exception( |
594 | string.Format( | 609 | string.Format( |
595 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", | 610 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", |
596 | ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH)); | 611 | ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH)); |
597 | 612 | ||
598 | if (m_assetsLoaded) | 613 | if (m_assetsLoaded) |
599 | throw new Exception( | 614 | throw new Exception( |
600 | string.Format( | 615 | string.Format( |
601 | "The IAR you are trying to load does not list all {0} before {1}. Aborting load", | 616 | "The IAR you are trying to load does not list all {0} before {1}. Aborting load", |
602 | ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); | 617 | ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); |
603 | 618 | ||
604 | path = path.Substring(ArchiveConstants.INVENTORY_PATH.Length); | 619 | path = path.Substring(ArchiveConstants.INVENTORY_PATH.Length); |
605 | 620 | ||
606 | // Trim off the file portion if we aren't already dealing with a directory path | 621 | // Trim off the file portion if we aren't already dealing with a directory path |
607 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) | 622 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) |
608 | path = path.Remove(path.LastIndexOf("/") + 1); | 623 | path = path.Remove(path.LastIndexOf("/") + 1); |
609 | 624 | ||
610 | InventoryFolderBase foundFolder | 625 | InventoryFolderBase foundFolder |
611 | = ReplicateArchivePathToUserInventory( | 626 | = ReplicateArchivePathToUserInventory( |
612 | path, m_rootDestinationFolder, m_resolvedFolders, m_loadedNodes); | 627 | path, m_rootDestinationFolder, m_resolvedFolders, m_loadedNodes); |
613 | 628 | ||
@@ -618,17 +633,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
618 | if (item != null) | 633 | if (item != null) |
619 | { | 634 | { |
620 | m_successfulItemRestores++; | 635 | m_successfulItemRestores++; |
621 | 636 | ||
622 | // If we aren't loading the folder containing the item then well need to update the | 637 | // If we aren't loading the folder containing the item then well need to update the |
623 | // viewer separately for that item. | 638 | // viewer separately for that item. |
624 | if (!m_loadedNodes.Contains(foundFolder)) | 639 | if (!m_loadedNodes.ContainsKey(foundFolder.ID)) |
625 | m_loadedNodes.Add(item); | 640 | m_loadedNodes[foundFolder.ID] = item; |
641 | } | ||
642 | } | ||
643 | |||
644 | m_inventoryNodesLoaded = true; | ||
645 | } | ||
646 | |||
647 | private void LoadInventoryLinks() | ||
648 | { | ||
649 | foreach(InventoryItemBase it in m_invLinks) | ||
650 | { | ||
651 | UUID target = it.AssetID; | ||
652 | if(m_itemIDs.ContainsKey(target)) | ||
653 | { | ||
654 | it.AssetID = m_itemIDs[target]; | ||
655 | if(!m_InventoryService.AddItem(it)) | ||
656 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}",it.Name,it.Folder); | ||
657 | else | ||
658 | { | ||
659 | m_successfulItemRestores++; | ||
660 | UUID fid = it.Folder; | ||
661 | if (!m_loadedNodes.ContainsKey(fid) && m_invLinksFolders.ContainsKey(fid)) | ||
662 | m_loadedNodes[fid] = m_invLinksFolders[fid]; | ||
663 | } | ||
626 | } | 664 | } |
627 | } | 665 | } |
628 | 666 | ||
629 | m_inventoryNodesLoaded = true; | 667 | m_itemIDs.Clear(); |
668 | m_invLinks.Clear(); | ||
669 | m_invLinksFolders.Clear(); | ||
630 | } | 670 | } |
631 | |||
632 | /// <summary> | 671 | /// <summary> |
633 | /// Load asset file | 672 | /// Load asset file |
634 | /// </summary> | 673 | /// </summary> |
@@ -639,15 +678,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
639 | if (!ControlFileLoaded) | 678 | if (!ControlFileLoaded) |
640 | throw new Exception( | 679 | throw new Exception( |
641 | string.Format( | 680 | string.Format( |
642 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", | 681 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", |
643 | ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.ASSETS_PATH)); | 682 | ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.ASSETS_PATH)); |
644 | 683 | ||
645 | if (!m_inventoryNodesLoaded) | 684 | if (!m_inventoryNodesLoaded) |
646 | throw new Exception( | 685 | throw new Exception( |
647 | string.Format( | 686 | string.Format( |
648 | "The IAR you are trying to load does not list all {0} before {1}. Aborting load", | 687 | "The IAR you are trying to load does not list all {0} before {1}. Aborting load", |
649 | ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); | 688 | ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); |
650 | 689 | ||
651 | if (LoadAsset(path, data)) | 690 | if (LoadAsset(path, data)) |
652 | m_successfulAssetRestores++; | 691 | m_successfulAssetRestores++; |
653 | else | 692 | else |
@@ -655,10 +694,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
655 | 694 | ||
656 | if ((m_successfulAssetRestores) % 50 == 0) | 695 | if ((m_successfulAssetRestores) % 50 == 0) |
657 | m_log.DebugFormat( | 696 | m_log.DebugFormat( |
658 | "[INVENTORY ARCHIVER]: Loaded {0} assets...", | 697 | "[INVENTORY ARCHIVER]: Loaded {0} assets...", |
659 | m_successfulAssetRestores); | 698 | m_successfulAssetRestores); |
660 | 699 | ||
661 | m_assetsLoaded = true; | 700 | m_assetsLoaded = true; |
662 | } | 701 | } |
663 | } | 702 | } |
664 | } | 703 | } |