aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorTeravus Ovares (Dan Olivares)2009-09-09 16:20:46 -0400
committerTeravus Ovares (Dan Olivares)2009-09-09 16:20:46 -0400
commitdf9f80aabd872c11711e1e4efb400a1921a9cab2 (patch)
treea7d5582ed1d763224727c8a6bdf9c1c94a674abd /OpenSim/Region/CoreModules
parent* Lock timers when Calling Start() and Stop() when the Thread Context is murk... (diff)
parentDe-hardcode default home locations on create user (standalone). (diff)
downloadopensim-SC_OLD-df9f80aabd872c11711e1e4efb400a1921a9cab2.zip
opensim-SC_OLD-df9f80aabd872c11711e1e4efb400a1921a9cab2.tar.gz
opensim-SC_OLD-df9f80aabd872c11711e1e4efb400a1921a9cab2.tar.bz2
opensim-SC_OLD-df9f80aabd872c11711e1e4efb400a1921a9cab2.tar.xz
Merge branch 'master' of ssh://MyConnection/var/git/opensim
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs158
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs48
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs141
-rw-r--r--OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs3
6 files changed, 330 insertions, 91 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 49b459a..6b0af6d 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -129,18 +129,18 @@ namespace Flotsam.RegionModules.AssetCache
129 if (name == Name) 129 if (name == Name)
130 { 130 {
131 m_Enabled = true; 131 m_Enabled = true;
132 m_log.InfoFormat("[ASSET CACHE]: {0} enabled", this.Name); 132 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name);
133 133
134 IConfig assetConfig = source.Configs["AssetCache"]; 134 IConfig assetConfig = source.Configs["AssetCache"];
135 if (assetConfig == null) 135 if (assetConfig == null)
136 { 136 {
137 m_log.Warn("[ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults."); 137 m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults.");
138 m_log.InfoFormat("[ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); 138 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
139 return; 139 return;
140 } 140 }
141 141
142 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); 142 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
143 m_log.InfoFormat("[ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); 143 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
144 144
145 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", true); 145 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", true);
146 m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); 146 m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
@@ -191,6 +191,8 @@ namespace Flotsam.RegionModules.AssetCache
191 } 191 }
192 192
193 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000); 193 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000);
194
195
194 } 196 }
195 } 197 }
196 } 198 }
@@ -206,7 +208,14 @@ namespace Flotsam.RegionModules.AssetCache
206 public void AddRegion(Scene scene) 208 public void AddRegion(Scene scene)
207 { 209 {
208 if (m_Enabled) 210 if (m_Enabled)
211 {
209 scene.RegisterModuleInterface<IImprovedAssetCache>(this); 212 scene.RegisterModuleInterface<IImprovedAssetCache>(this);
213
214 //scene.AddCommand(this, "flotsamcache", "", "Display a list of console commands for the Flotsam Asset Cache", HandleConsoleCommand);
215 scene.AddCommand(this, "flotsamcache counts", "flotsamcache counts", "Display the number of cached assets", HandleConsoleCommand);
216 scene.AddCommand(this, "flotsamcache clearmem", "flotsamcache clearmem", "Remove all assets cached in memory", HandleConsoleCommand);
217 scene.AddCommand(this, "flotsamcache clearfile", "flotsamcache clearfile", "Remove all assets cached on disk", HandleConsoleCommand);
218 }
210 } 219 }
211 220
212 public void RemoveRegion(Scene scene) 221 public void RemoveRegion(Scene scene)
@@ -368,16 +377,16 @@ namespace Flotsam.RegionModules.AssetCache
368 { 377 {
369 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 378 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
370 379
371 m_log.InfoFormat("[ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit"); 380 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit");
372 m_log.InfoFormat("[ASSET CACHE]: File Hit Rate {0}% for {1} requests", m_HitRateFile.ToString("0.00"), m_Requests); 381 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File Hit Rate {0}% for {1} requests", m_HitRateFile.ToString("0.00"), m_Requests);
373 382
374 if (m_MemoryCacheEnabled) 383 if (m_MemoryCacheEnabled)
375 { 384 {
376 m_HitRateMemory = (double)m_MemoryHits / m_Requests * 100.0; 385 m_HitRateMemory = (double)m_MemoryHits / m_Requests * 100.0;
377 m_log.InfoFormat("[ASSET CACHE]: Memory Hit Rate {0}% for {1} requests", m_HitRateMemory.ToString("0.00"), m_Requests); 386 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory Hit Rate {0}% for {1} requests", m_HitRateMemory.ToString("0.00"), m_Requests);
378 } 387 }
379 388
380 m_log.InfoFormat("[ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 389 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
381 390
382 } 391 }
383 392
@@ -387,7 +396,7 @@ namespace Flotsam.RegionModules.AssetCache
387 public void Expire(string id) 396 public void Expire(string id)
388 { 397 {
389 if (m_LogLevel >= 2) 398 if (m_LogLevel >= 2)
390 m_log.DebugFormat("[ASSET CACHE]: Expiring Asset {0}.", id); 399 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id);
391 400
392 try 401 try
393 { 402 {
@@ -409,7 +418,7 @@ namespace Flotsam.RegionModules.AssetCache
409 public void Clear() 418 public void Clear()
410 { 419 {
411 if (m_LogLevel >= 2) 420 if (m_LogLevel >= 2)
412 m_log.Debug("[ASSET CACHE]: Clearing Cache."); 421 m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing Cache.");
413 422
414 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 423 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
415 { 424 {
@@ -423,29 +432,42 @@ namespace Flotsam.RegionModules.AssetCache
423 private void CleanupExpiredFiles(object source, ElapsedEventArgs e) 432 private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
424 { 433 {
425 if (m_LogLevel >= 2) 434 if (m_LogLevel >= 2)
426 m_log.DebugFormat("[ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration.ToString()); 435 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration.ToString());
427 436
428 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 437 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
429 { 438 {
430 foreach (string file in Directory.GetFiles(dir)) 439 CleanExpiredFiles(dir);
431 { 440 }
432 if (DateTime.Now - File.GetLastAccessTime(file) > m_FileExpiration) 441 }
433 {
434 File.Delete(file);
435 }
436 }
437 442
438 int dirSize = Directory.GetFiles(dir).Length; 443 /// <summary>
439 if (dirSize == 0) 444 /// Recurses through specified directory checking for expired asset files and deletes them. Also removes empty directories.
440 { 445 /// </summary>
441 Directory.Delete(dir); 446 /// <param name="dir"></param>
442 } 447 private void CleanExpiredFiles(string dir)
443 else if (dirSize >= m_CacheWarnAt) 448 {
449 foreach (string file in Directory.GetFiles(dir))
450 {
451 if (DateTime.Now - File.GetLastAccessTime(file) > m_FileExpiration)
444 { 452 {
445 m_log.WarnFormat("[ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize); 453 File.Delete(file);
446 } 454 }
447
448 } 455 }
456
457 foreach (string subdir in Directory.GetDirectories(dir))
458 {
459 CleanExpiredFiles(subdir);
460 }
461
462 int dirSize = Directory.GetFiles(dir).Length + Directory.GetDirectories(dir).Length;
463 if (dirSize == 0)
464 {
465 Directory.Delete(dir);
466 }
467 else if (dirSize >= m_CacheWarnAt)
468 {
469 m_log.WarnFormat("[FLOTSAM ASSET CACHE]: Cache folder exceeded CacheWarnAt limit {0} {1}. Suggest increasing tiers, tier length, or reducing cache expiration", dir, dirSize);
470 }
449 } 471 }
450 472
451 private string GetFileName(string id) 473 private string GetFileName(string id)
@@ -489,7 +511,7 @@ namespace Flotsam.RegionModules.AssetCache
489 File.Move(tempname, filename); 511 File.Move(tempname, filename);
490 512
491 if (m_LogLevel >= 2) 513 if (m_LogLevel >= 2)
492 m_log.DebugFormat("[ASSET CACHE]: Cache Stored :: {0}", asset.ID); 514 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
493 } 515 }
494 catch (Exception e) 516 catch (Exception e)
495 { 517 {
@@ -525,8 +547,88 @@ namespace Flotsam.RegionModules.AssetCache
525 string[] text = e.ToString().Split(new char[] { '\n' }); 547 string[] text = e.ToString().Split(new char[] { '\n' });
526 foreach (string t in text) 548 foreach (string t in text)
527 { 549 {
528 m_log.ErrorFormat("[ASSET CACHE]: {0} ", t); 550 m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
551 }
552 }
553
554 private int GetFileCacheCount(string dir)
555 {
556 int count = Directory.GetFiles(dir).Length;
557
558 foreach (string subdir in Directory.GetDirectories(dir))
559 {
560 count += GetFileCacheCount(subdir);
529 } 561 }
562
563 return count;
530 } 564 }
565
566 #region Console Commands
567 private void HandleConsoleCommand(string module, string[] cmdparams)
568 {
569 if (cmdparams.Length == 2)
570 {
571 string cmd = cmdparams[1];
572 switch (cmd)
573 {
574 case "count":
575 case "counts":
576 m_log.InfoFormat("[FLOTSAM ASSET CACHE] Memory Cache : {0}", m_MemoryCache.Count);
577
578 int fileCount = GetFileCacheCount(m_CacheDirectory);
579 m_log.InfoFormat("[FLOTSAM ASSET CACHE] File Cache : {0}", fileCount);
580
581 break;
582
583 case "clearmem":
584 m_MemoryCache.Clear();
585 m_log.InfoFormat("[FLOTSAM ASSET CACHE] Memory Cache Cleared, there are now {0} items in the memory cache", m_MemoryCache.Count);
586 break;
587
588 case "clearfile":
589 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
590 {
591 try
592 {
593 Directory.Delete(dir, true);
594 }
595 catch (Exception e)
596 {
597 LogException(e);
598 }
599 }
600
601 foreach (string file in Directory.GetFiles(m_CacheDirectory))
602 {
603 try
604 {
605 File.Delete(file);
606 }
607 catch (Exception e)
608 {
609 LogException(e);
610 }
611 }
612
613 break;
614
615 default:
616 m_log.InfoFormat("[FLOTSAM ASSET CACHE] Unknown command {0}", cmd);
617 break;
618 }
619 }
620 else if (cmdparams.Length == 1)
621 {
622 m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache counts - Display the number of cached assets");
623 m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearmem - Remove all assets cached in memory");
624 m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearfile - Remove all assets cached on disk");
625
626 }
627
628
629 }
630
631 #endregion
632
531 } 633 }
532} 634}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index ff583e5..2a1c82e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -177,6 +177,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
177 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager); 177 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager);
178 if (UUID.Zero != ospResolvedId) 178 if (UUID.Zero != ospResolvedId)
179 item.CreatorIdAsUuid = ospResolvedId; 179 item.CreatorIdAsUuid = ospResolvedId;
180 else
181 item.CreatorIdAsUuid = m_userInfo.UserProfile.ID;
180 182
181 item.Owner = m_userInfo.UserProfile.ID; 183 item.Owner = m_userInfo.UserProfile.ID;
182 184
@@ -206,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 /// <summary> 208 /// <summary>
207 /// Replicate the inventory paths in the archive to the user's inventory as necessary. 209 /// Replicate the inventory paths in the archive to the user's inventory as necessary.
208 /// </summary> 210 /// </summary>
209 /// <param name="fsPath"></param> 211 /// <param name="archivePath">The item archive path to replicate</param>
210 /// <param name="isDir">Is the path we're dealing with a directory?</param> 212 /// <param name="isDir">Is the path we're dealing with a directory?</param>
211 /// <param name="rootDestinationFolder">The root folder for the inventory load</param> 213 /// <param name="rootDestinationFolder">The root folder for the inventory load</param>
212 /// <param name="foldersCreated"> 214 /// <param name="foldersCreated">
@@ -218,49 +220,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
218 /// </param> 220 /// </param>
219 /// <returns>The last user inventory folder created or found for the archive path</returns> 221 /// <returns>The last user inventory folder created or found for the archive path</returns>
220 public InventoryFolderBase ReplicateArchivePathToUserInventory( 222 public InventoryFolderBase ReplicateArchivePathToUserInventory(
221 string fsPath, 223 string archivePath,
222 bool isDir, 224 bool isDir,
223 InventoryFolderBase rootDestFolder, 225 InventoryFolderBase rootDestFolder,
224 Dictionary <string, InventoryFolderBase> foldersCreated, 226 Dictionary <string, InventoryFolderBase> foldersCreated,
225 List<InventoryNodeBase> nodesLoaded) 227 List<InventoryNodeBase> nodesLoaded)
226 { 228 {
227 fsPath = fsPath.Substring(ArchiveConstants.INVENTORY_PATH.Length); 229 archivePath = archivePath.Substring(ArchiveConstants.INVENTORY_PATH.Length);
228 230
229 // Remove the file portion if we aren't already dealing with a directory path 231 // Remove the file portion if we aren't already dealing with a directory path
230 if (!isDir) 232 if (!isDir)
231 fsPath = fsPath.Remove(fsPath.LastIndexOf("/") + 1); 233 archivePath = archivePath.Remove(archivePath.LastIndexOf("/") + 1);
232 234
233 string originalFsPath = fsPath; 235 string originalArchivePath = archivePath;
234 236
235 m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading to folder {0}", fsPath); 237 m_log.DebugFormat(
238 "[INVENTORY ARCHIVER]: Loading to folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
236 239
237 InventoryFolderBase destFolder = null; 240 InventoryFolderBase destFolder = null;
238 241
239 // XXX: Nasty way of dealing with a path that has no directory component 242 // XXX: Nasty way of dealing with a path that has no directory component
240 if (fsPath.Length > 0) 243 if (archivePath.Length > 0)
241 { 244 {
242 while (null == destFolder && fsPath.Length > 0) 245 while (null == destFolder && archivePath.Length > 0)
243 { 246 {
244 if (foldersCreated.ContainsKey(fsPath)) 247 if (foldersCreated.ContainsKey(archivePath))
245 { 248 {
246 m_log.DebugFormat("[INVENTORY ARCHIVER]: Found previously created fs path {0}", fsPath); 249 m_log.DebugFormat(
247 destFolder = foldersCreated[fsPath]; 250 "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
251 destFolder = foldersCreated[archivePath];
248 } 252 }
249 else 253 else
250 { 254 {
251 // Don't include the last slash 255 // Don't include the last slash
252 int penultimateSlashIndex = fsPath.LastIndexOf("/", fsPath.Length - 2); 256 int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2);
253 257
254 if (penultimateSlashIndex >= 0) 258 if (penultimateSlashIndex >= 0)
255 { 259 {
256 fsPath = fsPath.Remove(penultimateSlashIndex + 1); 260 archivePath = archivePath.Remove(penultimateSlashIndex + 1);
257 } 261 }
258 else 262 else
259 { 263 {
260 m_log.DebugFormat( 264 m_log.DebugFormat(
261 "[INVENTORY ARCHIVER]: Found no previously created fs path for {0}", 265 "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
262 originalFsPath); 266 originalArchivePath);
263 fsPath = string.Empty; 267 archivePath = string.Empty;
264 destFolder = rootDestFolder; 268 destFolder = rootDestFolder;
265 } 269 }
266 } 270 }
@@ -271,14 +275,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
271 destFolder = rootDestFolder; 275 destFolder = rootDestFolder;
272 } 276 }
273 277
274 string fsPathSectionToCreate = originalFsPath.Substring(fsPath.Length); 278 string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length);
275 string[] rawDirsToCreate 279 string[] rawDirsToCreate
276 = fsPathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); 280 = archivePathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
277 int i = 0; 281 int i = 0;
278 282
279 while (i < rawDirsToCreate.Length) 283 while (i < rawDirsToCreate.Length)
280 { 284 {
281 m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawDirsToCreate[i]); 285 m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading archived folder {0}", rawDirsToCreate[i]);
282 286
283 int identicalNameIdentifierIndex 287 int identicalNameIdentifierIndex
284 = rawDirsToCreate[i].LastIndexOf( 288 = rawDirsToCreate[i].LastIndexOf(
@@ -305,9 +309,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
305// foundFolder.Name, foundFolder.ID); 309// foundFolder.Name, foundFolder.ID);
306 310
307 // Record that we have now created this folder 311 // Record that we have now created this folder
308 fsPath += rawDirsToCreate[i] + "/"; 312 archivePath += rawDirsToCreate[i] + "/";
309 m_log.DebugFormat("[INVENTORY ARCHIVER]: Recording creation of fs path {0}", fsPath); 313 m_log.DebugFormat("[INVENTORY ARCHIVER]: Loaded archive path {0}", archivePath);
310 foldersCreated[fsPath] = destFolder; 314 foldersCreated[archivePath] = destFolder;
311 315
312 if (0 == i) 316 if (0 == i)
313 nodesLoaded.Add(destFolder); 317 nodesLoaded.Add(destFolder);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 2eeb637..5ebf2fa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -106,8 +106,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
106 if (path == PATH_DELIMITER) 106 if (path == PATH_DELIMITER)
107 return startFolder; 107 return startFolder;
108 108
109 InventoryFolderBase foundFolder = null;
110
111 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 109 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
112 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 110 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
113 111
@@ -116,7 +114,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
116 if (folder.Name == components[0]) 114 if (folder.Name == components[0])
117 { 115 {
118 if (components.Length > 1) 116 if (components.Length > 1)
119 return FindFolderByPath(inventoryService, foundFolder, components[1]); 117 return FindFolderByPath(inventoryService, folder, components[1]);
120 else 118 else
121 return folder; 119 return folder;
122 } 120 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index dee4a5d..b178772 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -138,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
138 138
139 protected void SaveInvItem(InventoryItemBase inventoryItem, string path) 139 protected void SaveInvItem(InventoryItemBase inventoryItem, string path)
140 { 140 {
141 string filename = string.Format("{0}{1}_{2}.xml", path, inventoryItem.Name, inventoryItem.ID); 141 string filename = path + CreateArchiveItemName(inventoryItem);
142 142
143 // Record the creator of this item for user record purposes (which might go away soon) 143 // Record the creator of this item for user record purposes (which might go away soon)
144 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1; 144 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;
@@ -162,12 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
162 { 162 {
163 if (saveThisFolderItself) 163 if (saveThisFolderItself)
164 { 164 {
165 path += 165 path += CreateArchiveFolderName(inventoryFolder);
166 string.Format(
167 "{0}{1}{2}/",
168 inventoryFolder.Name,
169 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
170 inventoryFolder.ID);
171 166
172 // We need to make sure that we record empty folders 167 // We need to make sure that we record empty folders
173 m_archiveWriter.WriteDir(path); 168 m_archiveWriter.WriteDir(path);
@@ -356,5 +351,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
356 } 351 }
357 } 352 }
358 } 353 }
354
355 /// <summary>
356 /// Create the archive name for a particular folder.
357 /// </summary>
358 ///
359 /// These names are prepended with an inventory folder's UUID so that more than one folder can have the
360 /// same name
361 ///
362 /// <param name="folder"></param>
363 /// <returns></returns>
364 public static string CreateArchiveFolderName(InventoryFolderBase folder)
365 {
366 return CreateArchiveFolderName(folder.Name, folder.ID);
367 }
368
369 /// <summary>
370 /// Create the archive name for a particular item.
371 /// </summary>
372 ///
373 /// These names are prepended with an inventory item's UUID so that more than one item can have the
374 /// same name
375 ///
376 /// <param name="item"></param>
377 /// <returns></returns>
378 public static string CreateArchiveItemName(InventoryItemBase item)
379 {
380 return CreateArchiveItemName(item.Name, item.ID);
381 }
382
383 /// <summary>
384 /// Create an archive folder name given its constituent components
385 /// </summary>
386 /// <param name="name"></param>
387 /// <param name="id"></param>
388 /// <returns></returns>
389 public static string CreateArchiveFolderName(string name, UUID id)
390 {
391 return string.Format(
392 "{0}{1}{2}/",
393 name,
394 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
395 id);
396 }
397
398 /// <summary>
399 /// Create an archive item name given its constituent components
400 /// </summary>
401 /// <param name="name"></param>
402 /// <param name="id"></param>
403 /// <returns></returns>
404 public static string CreateArchiveItemName(string name, UUID id)
405 {
406 return string.Format(
407 "{0}{1}{2}.xml",
408 name,
409 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
410 id);
411 }
359 } 412 }
360} 413}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index d579a81..9c5f8f3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
81 public void TestSaveIarV0_1() 81 public void TestSaveIarV0_1()
82 { 82 {
83 TestHelper.InMethod(); 83 TestHelper.InMethod();
84 log4net.Config.XmlConfigurator.Configure(); 84 //log4net.Config.XmlConfigurator.Configure();
85 85
86 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); 86 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
87 87
@@ -153,19 +153,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
153 //bool gotControlFile = false; 153 //bool gotControlFile = false;
154 bool gotObject1File = false; 154 bool gotObject1File = false;
155 //bool gotObject2File = false; 155 //bool gotObject2File = false;
156 string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
156 string expectedObject1FilePath = string.Format( 157 string expectedObject1FilePath = string.Format(
157 "{0}{1}/{2}_{3}.xml", 158 "{0}{1}{2}",
158 ArchiveConstants.INVENTORY_PATH, 159 ArchiveConstants.INVENTORY_PATH,
159 string.Format( 160 InventoryArchiveWriteRequest.CreateArchiveFolderName(objsFolder),
160 "Objects{0}{1}", ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, objsFolder.ID), 161 expectedObject1FileName);
161 item1.Name,
162 item1Id);
163
164// string expectedObject2FileName = string.Format(
165// "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
166// part2.Name,
167// Math.Round(part2.GroupPosition.X), Math.Round(part2.GroupPosition.Y), Math.Round(part2.GroupPosition.Z),
168// part2.UUID);
169 162
170 string filePath; 163 string filePath;
171 TarArchiveReader.TarEntryType tarEntryType; 164 TarArchiveReader.TarEntryType tarEntryType;
@@ -187,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
187// 180//
188// if (fileName.StartsWith(part1.Name)) 181// if (fileName.StartsWith(part1.Name))
189// { 182// {
190 Assert.That(filePath, Is.EqualTo(expectedObject1FilePath)); 183 Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
191 gotObject1File = true; 184 gotObject1File = true;
192// } 185// }
193// else if (fileName.StartsWith(part2.Name)) 186// else if (fileName.StartsWith(part2.Name))
@@ -202,19 +195,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
202 Assert.That(gotObject1File, Is.True, "No item1 file in archive"); 195 Assert.That(gotObject1File, Is.True, "No item1 file in archive");
203// Assert.That(gotObject2File, Is.True, "No object2 file in archive"); 196// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
204 197
205 // TODO: Test presence of more files and contents of files. 198 // TODO: Test presence of more files and contents of files.
206 } 199 }
207 200
208 /// <summary> 201 /// <summary>
209 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 202 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
210 /// an account exists with the creator name. 203 /// an account exists with the creator name.
211 /// </summary> 204 /// </summary>
205 ///
206 /// This test also does some deeper probing of loading into nested inventory structures
212 [Test] 207 [Test]
213 public void TestLoadIarV0_1ExistingUsers() 208 public void TestLoadIarV0_1ExistingUsers()
214 { 209 {
215 TestHelper.InMethod(); 210 TestHelper.InMethod();
216 211
217 log4net.Config.XmlConfigurator.Configure(); 212 //log4net.Config.XmlConfigurator.Configure();
218 213
219 string userFirstName = "Mr"; 214 string userFirstName = "Mr";
220 string userLastName = "Tiddles"; 215 string userLastName = "Tiddles";
@@ -264,24 +259,114 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
264 CachedUserInfo userInfo 259 CachedUserInfo userInfo
265 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); 260 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
266 261
267 InventoryItemBase foundItem 262 InventoryItemBase foundItem1
268 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName); 263 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName);
269 264
270 Assert.That(foundItem, Is.Not.Null, "Didn't find loaded item"); 265 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
271 Assert.That( 266 Assert.That(
272 foundItem.CreatorId, Is.EqualTo(item1.CreatorId), 267 foundItem1.CreatorId, Is.EqualTo(item1.CreatorId),
273 "Loaded item non-uuid creator doesn't match original"); 268 "Loaded item non-uuid creator doesn't match original");
274 Assert.That( 269 Assert.That(
275 foundItem.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid), 270 foundItem1.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid),
276 "Loaded item uuid creator doesn't match original"); 271 "Loaded item uuid creator doesn't match original");
277 Assert.That(foundItem.Owner, Is.EqualTo(userUuid), 272 Assert.That(foundItem1.Owner, Is.EqualTo(userUuid),
278 "Loaded item owner doesn't match inventory reciever"); 273 "Loaded item owner doesn't match inventory reciever");
274
275 // Now try loading to a root child folder
276 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userInfo.UserProfile.ID, "xA");
277 archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
278 archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", archiveReadStream);
279
280 InventoryItemBase foundItem2
281 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + itemName);
282 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
283
284 // Now try loading to a more deeply nested folder
285 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC");
286 archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
287 archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", archiveReadStream);
288
289 InventoryItemBase foundItem3
290 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + itemName);
291 Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
279 } 292 }
280 293
281 /// <summary> 294 /// <summary>
282 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 295 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
296 /// embedded creators do not exist in the system
297 /// </summary>
298 ///
299 /// This may possibly one day get overtaken by the as yet incomplete temporary profiles feature
300 /// (as tested in the a later commented out test)
301 [Test]
302 public void TestLoadIarV0_1AbsentUsers()
303 {
304 TestHelper.InMethod();
305
306 log4net.Config.XmlConfigurator.Configure();
307
308 string userFirstName = "Charlie";
309 string userLastName = "Chan";
310 UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000999");
311 string userItemCreatorFirstName = "Bat";
312 string userItemCreatorLastName = "Man";
313 //UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000008888");
314
315 string itemName = "b.lsl";
316 string archiveItemName
317 = string.Format("{0}{1}{2}", itemName, "_", UUID.Random());
318
319 MemoryStream archiveWriteStream = new MemoryStream();
320 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
321
322 InventoryItemBase item1 = new InventoryItemBase();
323 item1.Name = itemName;
324 item1.AssetID = UUID.Random();
325 item1.GroupID = UUID.Random();
326 item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
327 //item1.CreatorId = userUuid.ToString();
328 //item1.CreatorId = "00000000-0000-0000-0000-000000000444";
329 item1.Owner = UUID.Zero;
330
331 string item1FileName
332 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
333 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
334 tar.Close();
335
336 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
337 SerialiserModule serialiserModule = new SerialiserModule();
338 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
339
340 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
341 Scene scene = SceneSetupHelpers.SetupScene("inventory");
342 IUserAdminService userAdminService = scene.CommsManager.UserAdminService;
343
344 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
345 userAdminService.AddUser(
346 userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);
347
348 archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream);
349
350 CachedUserInfo userInfo
351 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
352
353 InventoryItemBase foundItem1
354 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName);
355
356 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
357// Assert.That(
358// foundItem1.CreatorId, Is.EqualTo(userUuid),
359// "Loaded item non-uuid creator doesn't match that of the loading user");
360 Assert.That(
361 foundItem1.CreatorIdAsUuid, Is.EqualTo(userUuid),
362 "Loaded item uuid creator doesn't match that of the loading user");
363 }
364
365 /// <summary>
366 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
283 /// no account exists with the creator name 367 /// no account exists with the creator name
284 /// </summary> 368 /// </summary>
369 /// Disabled since temporary profiles have not yet been implemented.
285 //[Test] 370 //[Test]
286 public void TestLoadIarV0_1TempProfiles() 371 public void TestLoadIarV0_1TempProfiles()
287 { 372 {
@@ -364,7 +449,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
364 { 449 {
365 TestHelper.InMethod(); 450 TestHelper.InMethod();
366 451
367 log4net.Config.XmlConfigurator.Configure(); 452 //log4net.Config.XmlConfigurator.Configure();
368 453
369 Scene scene = SceneSetupHelpers.SetupScene("inventory"); 454 Scene scene = SceneSetupHelpers.SetupScene("inventory");
370 CommunicationsManager commsManager = scene.CommsManager; 455 CommunicationsManager commsManager = scene.CommsManager;
@@ -385,16 +470,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
385 string folder2Name = "b"; 470 string folder2Name = "b";
386 string itemName = "c.lsl"; 471 string itemName = "c.lsl";
387 472
388 string folder1ArchiveName 473 string folder1ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder1Name, UUID.Random());
389 = string.Format( 474 string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random());
390 "{0}{1}{2}", folder1Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random()); 475 string itemArchiveName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random());
391 string folder2ArchiveName 476
392 = string.Format(
393 "{0}{1}{2}", folder2Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random());
394 string itemArchivePath 477 string itemArchivePath
395 = string.Format( 478 = string.Format(
396 "{0}{1}/{2}/{3}", 479 "{0}{1}{2}{3}",
397 ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemName); 480 ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemArchiveName);
398 481
399 //Console.WriteLine("userInfo.RootFolder 2: {0}", userInfo.RootFolder); 482 //Console.WriteLine("userInfo.RootFolder 2: {0}", userInfo.RootFolder);
400 483
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
index 9da869c..f513d68 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
@@ -588,10 +588,9 @@ namespace OpenSim.Region.CoreModules.World.Land
588 RegionConnections connectiondata, ScenePresence rootPresence) 588 RegionConnections connectiondata, ScenePresence rootPresence)
589 { 589 {
590 RegionData[] rdata = connectiondata.ConnectedRegions.ToArray(); 590 RegionData[] rdata = connectiondata.ConnectedRegions.ToArray();
591 List<IClientAPI> clients = new List<IClientAPI>(); 591 //List<IClientAPI> clients = new List<IClientAPI>();
592 Dictionary<Vector2, RegionCourseLocationStruct> updates = new Dictionary<Vector2, RegionCourseLocationStruct>(); 592 Dictionary<Vector2, RegionCourseLocationStruct> updates = new Dictionary<Vector2, RegionCourseLocationStruct>();
593 593
594
595 // Root Region entry 594 // Root Region entry
596 RegionCourseLocationStruct rootupdatedata = new RegionCourseLocationStruct(); 595 RegionCourseLocationStruct rootupdatedata = new RegionCourseLocationStruct();
597 rootupdatedata.Locations = new List<Vector3>(); 596 rootupdatedata.Locations = new List<Vector3>();