aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs21
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs704
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs10
8 files changed, 112 insertions, 713 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 59b30a9..7d9c9a9 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -776,7 +776,6 @@ namespace OpenSim.Region.CoreModules.Asset
776 { 776 {
777 UuidGatherer gatherer = new UuidGatherer(m_AssetService); 777 UuidGatherer gatherer = new UuidGatherer(m_AssetService);
778 778
779 Dictionary<UUID, sbyte> assetIdsToCheck = new Dictionary<UUID, sbyte>();
780 Dictionary<UUID, bool> assetsFound = new Dictionary<UUID, bool>(); 779 Dictionary<UUID, bool> assetsFound = new Dictionary<UUID, bool>();
781 780
782 foreach (Scene s in m_Scenes) 781 foreach (Scene s in m_Scenes)
@@ -784,10 +783,11 @@ namespace OpenSim.Region.CoreModules.Asset
784 StampRegionStatusFile(s.RegionInfo.RegionID); 783 StampRegionStatusFile(s.RegionInfo.RegionID);
785 784
786 s.ForEachSOG(delegate(SceneObjectGroup e) 785 s.ForEachSOG(delegate(SceneObjectGroup e)
787 { 786 {
788 gatherer.GatherAssetUuids(e, assetIdsToCheck); 787 gatherer.AddForInspection(e);
788 gatherer.GatherAll();
789 789
790 foreach (UUID assetID in assetIdsToCheck.Keys) 790 foreach (UUID assetID in gatherer.GatheredUuids.Keys)
791 { 791 {
792 if (!assetsFound.ContainsKey(assetID)) 792 if (!assetsFound.ContainsKey(assetID))
793 { 793 {
@@ -800,7 +800,7 @@ namespace OpenSim.Region.CoreModules.Asset
800 else if (storeUncached) 800 else if (storeUncached)
801 { 801 {
802 AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); 802 AssetBase cachedAsset = m_AssetService.Get(assetID.ToString());
803 if (cachedAsset == null && assetIdsToCheck[assetID] != (sbyte)AssetType.Unknown) 803 if (cachedAsset == null && gatherer.GatheredUuids[assetID] != (sbyte)AssetType.Unknown)
804 assetsFound[assetID] = false; 804 assetsFound[assetID] = false;
805 else 805 else
806 assetsFound[assetID] = true; 806 assetsFound[assetID] = true;
@@ -810,11 +810,11 @@ namespace OpenSim.Region.CoreModules.Asset
810 { 810 {
811 m_log.DebugFormat( 811 m_log.DebugFormat(
812 "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", 812 "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets",
813 assetID, assetIdsToCheck[assetID], e.Name, e.AbsolutePosition, s.Name); 813 assetID, gatherer.GatheredUuids[assetID], e.Name, e.AbsolutePosition, s.Name);
814 } 814 }
815 } 815 }
816 816
817 assetIdsToCheck.Clear(); 817 gatherer.GatheredUuids.Clear();
818 }); 818 });
819 } 819 }
820 820
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 6dab227..42a4c7a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -94,11 +94,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
94 protected UUID m_id; 94 protected UUID m_id;
95 95
96 /// <value> 96 /// <value>
97 /// Used to collect the uuids of the assets that we need to save into the archive
98 /// </value>
99 protected Dictionary<UUID, sbyte> m_assetUuids = new Dictionary<UUID, sbyte>();
100
101 /// <value>
102 /// Used to collect the uuids of the users that we need to save into the archive 97 /// Used to collect the uuids of the users that we need to save into the archive
103 /// </value> 98 /// </value>
104 protected Dictionary<UUID, int> m_userUuids = new Dictionary<UUID, int>(); 99 protected Dictionary<UUID, int> m_userUuids = new Dictionary<UUID, int>();
@@ -225,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
225 220
226 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset 221 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
227 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) 222 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
228 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (sbyte)inventoryItem.AssetType, m_assetUuids); 223 m_assetGatherer.AddForInspection(inventoryItem.AssetID);
229 } 224 }
230 225
231 /// <summary> 226 /// <summary>
@@ -422,12 +417,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
422 417
423 if (SaveAssets) 418 if (SaveAssets)
424 { 419 {
425 m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); 420 m_assetGatherer.GatherAll();
421
422 m_log.DebugFormat(
423 "[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count);
426 424
427 AssetsRequest ar 425 AssetsRequest ar
428 = new AssetsRequest( 426 = new AssetsRequest(
429 new AssetsArchiver(m_archiveWriter), 427 new AssetsArchiver(m_archiveWriter),
430 m_assetUuids, m_scene.AssetService, 428 m_assetGatherer.GatheredUuids, m_scene.AssetService,
431 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 429 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
432 options, ReceivedAllAssets); 430 options, ReceivedAllAssets);
433 431
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 2ddb599..fceda80 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -605,8 +605,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
605 // so.Name, so.AttachedAvatar, url); 605 // so.Name, so.AttachedAvatar, url);
606 606
607 IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); 607 IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
608 IteratingHGUuidGatherer uuidGatherer 608 HGUuidGatherer uuidGatherer
609 = new IteratingHGUuidGatherer(Scene.AssetService, url, ids); 609 = new HGUuidGatherer(Scene.AssetService, url, ids);
610 uuidGatherer.AddForInspection(so); 610 uuidGatherer.AddForInspection(so);
611 611
612 while (!uuidGatherer.Complete) 612 while (!uuidGatherer.Complete)
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index 2ac1517..6343a81 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -412,12 +412,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
412 412
413 // The act of gathering UUIDs downloads some assets from the remote server 413 // The act of gathering UUIDs downloads some assets from the remote server
414 // but not all... 414 // but not all...
415 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
416 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); 415 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
417 uuidGatherer.GatherAssetUuids(assetID, meta.Type, ids); 416 uuidGatherer.AddForInspection(assetID);
418 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); 417 uuidGatherer.GatherAll();
418
419 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", uuidGatherer.GatheredUuids.Count);
419 bool success = true; 420 bool success = true;
420 foreach (UUID uuid in ids.Keys) 421 foreach (UUID uuid in uuidGatherer.GatheredUuids.Keys)
421 if (FetchAsset(userAssetURL, uuid) == null) 422 if (FetchAsset(userAssetURL, uuid) == null)
422 success = false; 423 success = false;
423 424
@@ -428,7 +429,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
428 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL); 429 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL);
429 } 430 }
430 431
431
432 public void Post(UUID assetID, UUID ownerID, string userAssetURL) 432 public void Post(UUID assetID, UUID ownerID, string userAssetURL)
433 { 433 {
434 m_log.DebugFormat("[HG ASSET MAPPER]: Starting to send asset {0} with children to asset server {1}", assetID, userAssetURL); 434 m_log.DebugFormat("[HG ASSET MAPPER]: Starting to send asset {0} with children to asset server {1}", assetID, userAssetURL);
@@ -442,9 +442,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
442 return; 442 return;
443 } 443 }
444 444
445 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
446 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); 445 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
447 uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids); 446 uuidGatherer.AddForInspection(asset.FullID);
448 447
449 // Check which assets already exist in the destination server 448 // Check which assets already exist in the destination server
450 449
@@ -452,16 +451,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
452 if (!url.EndsWith("/") && !url.EndsWith("=")) 451 if (!url.EndsWith("/") && !url.EndsWith("="))
453 url = url + "/"; 452 url = url + "/";
454 453
455 string[] remoteAssetIDs = new string[ids.Count]; 454 string[] remoteAssetIDs = new string[uuidGatherer.GatheredUuids.Count];
456 int i = 0; 455 int i = 0;
457 foreach (UUID id in ids.Keys) 456 foreach (UUID id in uuidGatherer.GatheredUuids.Keys)
458 remoteAssetIDs[i++] = url + id.ToString(); 457 remoteAssetIDs[i++] = url + id.ToString();
459 458
460 bool[] exist = m_scene.AssetService.AssetsExist(remoteAssetIDs); 459 bool[] exist = m_scene.AssetService.AssetsExist(remoteAssetIDs);
461 460
462 var existSet = new HashSet<string>(); 461 var existSet = new HashSet<string>();
463 i = 0; 462 i = 0;
464 foreach (UUID id in ids.Keys) 463 foreach (UUID id in uuidGatherer.GatheredUuids.Keys)
465 { 464 {
466 if (exist[i]) 465 if (exist[i])
467 existSet.Add(id.ToString()); 466 existSet.Add(id.ToString());
@@ -472,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
472 471
473 bool success = true; 472 bool success = true;
474 473
475 foreach (UUID uuid in ids.Keys) 474 foreach (UUID uuid in uuidGatherer.GatheredUuids.Keys)
476 { 475 {
477 if (!existSet.Contains(uuid.ToString())) 476 if (!existSet.Contains(uuid.ToString()))
478 { 477 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index b7d7c26..d67bdce 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -219,7 +219,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
219 219
220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids) 220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids)
221 { 221 {
222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); 222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name);
223 223
224 EntityBase[] entities = scene.GetEntities(); 224 EntityBase[] entities = scene.GetEntities();
225 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 225 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
@@ -253,13 +253,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
253 253
254 if (SaveAssets) 254 if (SaveAssets)
255 { 255 {
256 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService); 256 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids);
257 int prevAssets = assetUuids.Count; 257 int prevAssets = assetUuids.Count;
258 258
259 foreach (SceneObjectGroup sceneObject in sceneObjects) 259 foreach (SceneObjectGroup sceneObject in sceneObjects)
260 { 260 assetGatherer.AddForInspection(sceneObject);
261 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 261
262 } 262 assetGatherer.GatherAll();
263 263
264 m_log.DebugFormat( 264 m_log.DebugFormat(
265 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", 265 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index a12b170..1fe0e79 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -61,11 +61,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero); 61 = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero);
62 m_assetService.Store(corruptAsset); 62 m_assetService.Store(corruptAsset);
63 63
64 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>(); 64 m_uuidGatherer.AddForInspection(corruptAssetUuid);
65 m_uuidGatherer.GatherAssetUuids(corruptAssetUuid, (sbyte)AssetType.Object, foundAssetUuids); 65 m_uuidGatherer.GatherAll();
66 66
67 // We count the uuid as gathered even if the asset itself is corrupt. 67 // We count the uuid as gathered even if the asset itself is corrupt.
68 Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); 68 Assert.That(m_uuidGatherer.GatheredUuids.Count, Is.EqualTo(1));
69 } 69 }
70 70
71 /// <summary> 71 /// <summary>
@@ -77,38 +77,42 @@ namespace OpenSim.Region.Framework.Scenes.Tests
77 TestHelpers.InMethod(); 77 TestHelpers.InMethod();
78 78
79 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 79 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
80 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>();
81
82 m_uuidGatherer.GatherAssetUuids(missingAssetUuid, (sbyte)AssetType.Object, foundAssetUuids);
83 80
84 // We count the uuid as gathered even if the asset itself is missing. 81 m_uuidGatherer.AddForInspection(missingAssetUuid);
85 Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); 82 m_uuidGatherer.GatherAll();
83
84 Assert.That(m_uuidGatherer.GatheredUuids.Count, Is.EqualTo(0));
86 } 85 }
87 86
88 [Test] 87 [Test]
89 public void TestNotecardAsset() 88 public void TestNotecardAsset()
90 { 89 {
91 TestHelpers.InMethod(); 90 TestHelpers.InMethod();
92// log4net.Config.XmlConfigurator.Configure(); 91 TestHelpers.EnableLogging();
93 92
94 UUID ownerId = TestHelpers.ParseTail(0x10); 93 UUID ownerId = TestHelpers.ParseTail(0x10);
95 UUID soAssetId = TestHelpers.ParseTail(0x20); 94 UUID embeddedId = TestHelpers.ParseTail(0x20);
95 UUID missingEmbeddedId = TestHelpers.ParseTail(0x21);
96 UUID ncAssetId = TestHelpers.ParseTail(0x30); 96 UUID ncAssetId = TestHelpers.ParseTail(0x30);
97 97
98 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId); 98 AssetBase ncAsset
99 AssetBase soAsset = AssetHelpers.CreateAsset(soAssetId, so); 99 = AssetHelpers.CreateNotecardAsset(
100 m_assetService.Store(soAsset); 100 ncAssetId, string.Format("Hello{0}World{1}", embeddedId, missingEmbeddedId));
101
102 AssetBase ncAsset = AssetHelpers.CreateNotecardAsset(ncAssetId, soAssetId.ToString());
103 m_assetService.Store(ncAsset); 101 m_assetService.Store(ncAsset);
104 102
105 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>(); 103 AssetBase embeddedAsset = AssetHelpers.CreateNotecardAsset(embeddedId, "We'll meet again.");
106 m_uuidGatherer.GatherAssetUuids(ncAssetId, (sbyte)AssetType.Notecard, foundAssetUuids); 104 m_assetService.Store(embeddedAsset);
107 105
108 // We count the uuid as gathered even if the asset itself is corrupt. 106 m_uuidGatherer.AddForInspection(ncAssetId);
109 Assert.That(foundAssetUuids.Count, Is.EqualTo(2)); 107 m_uuidGatherer.GatherAll();
110 Assert.That(foundAssetUuids.ContainsKey(ncAssetId)); 108
111 Assert.That(foundAssetUuids.ContainsKey(soAssetId)); 109// foreach (UUID key in m_uuidGatherer.GatheredUuids.Keys)
110// System.Console.WriteLine("key : {0}", key);
111
112 Assert.That(m_uuidGatherer.GatheredUuids.Count, Is.EqualTo(3));
113 Assert.That(m_uuidGatherer.GatheredUuids.ContainsKey(ncAssetId));
114 Assert.That(m_uuidGatherer.GatheredUuids.ContainsKey(embeddedId));
115 Assert.That(m_uuidGatherer.GatheredUuids.ContainsKey(missingEmbeddedId));
112 } 116 }
113 } 117 }
114} 118} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 2c5353f..28653c6 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -55,616 +55,16 @@ namespace OpenSim.Region.Framework.Scenes
55 { 55 {
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57 57
58 protected IAssetService m_assetService;
59
60 // /// <summary>
61 // /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
62 // /// asset was found by the asset service.
63 // /// </summary>
64 // private AssetBase m_requestedObjectAsset;
65 //
66 // /// <summary>
67 // /// Signal whether we are currently waiting for the asset service to deliver an asset.
68 // /// </summary>
69 // private bool m_waitingForObjectAsset;
70
71 public UuidGatherer(IAssetService assetService)
72 {
73 m_assetService = assetService;
74 }
75
76 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary>
79 /// <remarks>
80 /// This includes both those directly associated with
81 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
82 /// within this object).
83 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
84 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
85 /// is of a type which is known not to reference any other assets
86 /// </remarks>
87 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
88 /// <param name="assetUuids">The assets gathered</param>
89 public void GatherAssetUuids(UUID assetUuid, IDictionary<UUID, sbyte> assetUuids)
90 {
91 // avoid infinite loops
92 if (assetUuids.ContainsKey(assetUuid))
93 return;
94
95 try
96 {
97 AssetBase assetBase = GetAsset(assetUuid);
98
99 if (null != assetBase)
100 {
101 sbyte assetType = assetBase.Type;
102 assetUuids[assetUuid] = assetType;
103
104 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
105 {
106 GetWearableAssetUuids(assetBase, assetUuids);
107 }
108 else if ((sbyte)AssetType.Gesture == assetType)
109 {
110 GetGestureAssetUuids(assetBase, assetUuids);
111 }
112 else if ((sbyte)AssetType.Notecard == assetType)
113 {
114 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
115 }
116 else if ((sbyte)AssetType.LSLText == assetType)
117 {
118 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
119 }
120 else if ((sbyte)OpenSimAssetType.Material == assetType)
121 {
122 GetMaterialAssetUuids(assetBase, assetUuids);
123 }
124 else if ((sbyte)AssetType.Object == assetType)
125 {
126 GetSceneObjectAssetUuids(assetBase, assetUuids);
127 }
128 }
129 }
130 catch (Exception)
131 {
132 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
133 throw;
134 }
135 }
136
137 /// <summary>
138 /// Gather all the asset uuids associated with the asset referenced by a given uuid
139 /// </summary>
140 /// <remarks>
141 /// This includes both those directly associated with
142 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
143 /// within this object).
144 /// </remarks>
145 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
146 /// <param name="assetType">The type of the asset for the uuid given</param>
147 /// <param name="assetUuids">The assets gathered</param>
148 public void GatherAssetUuids(UUID assetUuid, sbyte assetType, IDictionary<UUID, sbyte> assetUuids)
149 {
150 // avoid infinite loops
151 if (assetUuids.ContainsKey(assetUuid))
152 return;
153
154 try
155 {
156 assetUuids[assetUuid] = assetType;
157
158 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
159 {
160 GetWearableAssetUuids(assetUuid, assetUuids);
161 }
162 else if ((sbyte)AssetType.Gesture == assetType)
163 {
164 GetGestureAssetUuids(assetUuid, assetUuids);
165 }
166 else if ((sbyte)AssetType.Notecard == assetType)
167 {
168 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
169 }
170 else if ((sbyte)AssetType.LSLText == assetType)
171 {
172 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
173 }
174 else if ((sbyte)OpenSimAssetType.Material == assetType)
175 {
176 GetMaterialAssetUuids(assetUuid, assetUuids);
177 }
178 else if ((sbyte)AssetType.Object == assetType)
179 {
180 GetSceneObjectAssetUuids(assetUuid, assetUuids);
181 }
182 }
183 catch (Exception)
184 {
185 m_log.ErrorFormat(
186 "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
187 assetUuid, assetType);
188 throw;
189 }
190 }
191
192 /// <summary>
193 /// Gather all the asset uuids associated with a given object.
194 /// </summary>
195 /// <remarks>
196 /// This includes both those directly associated with
197 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
198 /// within this object).
199 /// </remarks>
200 /// <param name="sceneObject">The scene object for which to gather assets</param>
201 /// <param name="assetUuids">
202 /// A dictionary which is populated with the asset UUIDs gathered and the type of that asset.
203 /// For assets where the type is not clear (e.g. UUIDs extracted from LSL and notecards), the type is Unknown.
204 /// </param>
205 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids)
206 {
207 // m_log.DebugFormat(
208 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
209
210 SceneObjectPart[] parts = sceneObject.Parts;
211 for (int i = 0; i < parts.Length; i++)
212 {
213 SceneObjectPart part = parts[i];
214
215 // m_log.DebugFormat(
216 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
217
218 try
219 {
220 Primitive.TextureEntry textureEntry = part.Shape.Textures;
221 if (textureEntry != null)
222 {
223 // Get the prim's default texture. This will be used for faces which don't have their own texture
224 if (textureEntry.DefaultTexture != null)
225 GatherTextureEntryAssets(textureEntry.DefaultTexture, assetUuids);
226
227 if (textureEntry.FaceTextures != null)
228 {
229 // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
230 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
231 {
232 if (texture != null)
233 GatherTextureEntryAssets(texture, assetUuids);
234 }
235 }
236 }
237
238 // If the prim is a sculpt then preserve this information too
239 if (part.Shape.SculptTexture != UUID.Zero)
240 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
241
242 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
243 assetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
244
245 if (part.CollisionSound != UUID.Zero)
246 assetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
247
248 if (part.ParticleSystem.Length > 0)
249 {
250 try
251 {
252 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
253 if (ps.Texture != UUID.Zero)
254 assetUuids[ps.Texture] = (sbyte)AssetType.Texture;
255 }
256 catch (Exception)
257 {
258 m_log.WarnFormat(
259 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
260 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
261 }
262 }
263
264 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
265
266 // Now analyze this prim's inventory items to preserve all the uuids that they reference
267 foreach (TaskInventoryItem tii in taskDictionary.Values)
268 {
269 // m_log.DebugFormat(
270 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
271 // tii.Name, tii.Type, part.Name, part.UUID);
272
273 if (!assetUuids.ContainsKey(tii.AssetID))
274 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids);
275 }
276
277 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
278 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
279 // inventory transfer. There needs to be a way for a module to register a method without assuming a
280 // Scene.EventManager is present.
281 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
282
283
284 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
285 GatherMaterialsUuids(part, assetUuids);
286 }
287 catch (Exception e)
288 {
289 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
290 m_log.DebugFormat(
291 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
292 part.Shape.TextureEntry.Length);
293 }
294 }
295 }
296
297 /// <summary>
298 /// Gather all the asset uuids found in one face of a Texture Entry.
299 /// </summary>
300 private void GatherTextureEntryAssets(Primitive.TextureEntryFace texture, IDictionary<UUID, sbyte> assetUuids)
301 {
302 assetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
303
304 if (texture.MaterialID != UUID.Zero)
305 {
306 GatherAssetUuids(texture.MaterialID, (sbyte)OpenSimAssetType.Material, assetUuids);
307 }
308 }
309
310 /// <summary>
311 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
312 /// stored in legacy format in part.DynAttrs
313 /// </summary>
314 /// <param name="part"></param>
315 /// <param name="assetUuids"></param>
316 //public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids)
317 public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, sbyte> assetUuids)
318 {
319 // scan thru the dynAttrs map of this part for any textures used as materials
320 OSD osdMaterials = null;
321
322 lock (part.DynAttrs)
323 {
324 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
325 {
326 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
327
328 if (materialsStore == null)
329 return;
330
331 materialsStore.TryGetValue("Materials", out osdMaterials);
332 }
333
334 if (osdMaterials != null)
335 {
336 //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
337
338 if (osdMaterials is OSDArray)
339 {
340 OSDArray matsArr = osdMaterials as OSDArray;
341 foreach (OSDMap matMap in matsArr)
342 {
343 try
344 {
345 if (matMap.ContainsKey("Material"))
346 {
347 OSDMap mat = matMap["Material"] as OSDMap;
348 if (mat.ContainsKey("NormMap"))
349 {
350 UUID normalMapId = mat["NormMap"].AsUUID();
351 if (normalMapId != UUID.Zero)
352 {
353 assetUuids[normalMapId] = (sbyte)AssetType.Texture;
354 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
355 }
356 }
357 if (mat.ContainsKey("SpecMap"))
358 {
359 UUID specularMapId = mat["SpecMap"].AsUUID();
360 if (specularMapId != UUID.Zero)
361 {
362 assetUuids[specularMapId] = (sbyte)AssetType.Texture;
363 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
364 }
365 }
366 }
367
368 }
369 catch (Exception e)
370 {
371 m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message);
372 }
373 }
374 }
375 }
376 }
377 }
378
379 /// <summary>
380 /// Get an asset synchronously, potentially using an asynchronous callback. If the
381 /// asynchronous callback is used, we will wait for it to complete.
382 /// </summary>
383 /// <param name="uuid"></param>
384 /// <returns></returns>
385 protected virtual AssetBase GetAsset(UUID uuid)
386 {
387 return m_assetService.Get(uuid.ToString());
388
389 // XXX: Switching to do this synchronously where the call was async before but we always waited for it
390 // to complete anyway!
391 // m_waitingForObjectAsset = true;
392 // m_assetCache.Get(uuid.ToString(), this, AssetReceived);
393 //
394 // // The asset cache callback can either
395 // //
396 // // 1. Complete on the same thread (if the asset is already in the cache) or
397 // // 2. Come in via a different thread (if we need to go fetch it).
398 // //
399 // // The code below handles both these alternatives.
400 // lock (this)
401 // {
402 // if (m_waitingForObjectAsset)
403 // {
404 // Monitor.Wait(this);
405 // m_waitingForObjectAsset = false;
406 // }
407 // }
408 //
409 // return m_requestedObjectAsset;
410 }
411
412 /// <summary>
413 /// Record the asset uuids embedded within the given text (e.g. a script).
414 /// </summary>
415 /// <param name="textAssetUuid"></param>
416 /// <param name="assetUuids">Dictionary in which to record the references</param>
417 private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids)
418 {
419 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
420
421 AssetBase textAsset = GetAsset(textAssetUuid);
422
423 if (null != textAsset)
424 GetTextEmbeddedAssetUuids(textAsset, assetUuids);
425 }
426
427 /// <summary> 58 /// <summary>
428 /// Record the asset uuids embedded within the given text (e.g. a script). 59 /// Is gathering complete?
429 /// </summary>
430 /// <param name="textAsset"></param>
431 /// <param name="assetUuids">Dictionary in which to record the references</param>
432 private void GetTextEmbeddedAssetUuids(AssetBase textAsset, IDictionary<UUID, sbyte> assetUuids)
433 {
434 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
435
436 string script = Utils.BytesToString(textAsset.Data);
437 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
438 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
439 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
440
441 foreach (Match uuidMatch in uuidMatches)
442 {
443 UUID uuid = new UUID(uuidMatch.Value);
444 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
445
446 // Embedded asset references (if not false positives) could be for many types of asset, so we will
447 // label these as unknown.
448 assetUuids[uuid] = (sbyte)AssetType.Unknown;
449 }
450 }
451
452 /// <summary>
453 /// Record the uuids referenced by the given wearable asset
454 /// </summary>
455 /// <param name="wearableAssetUuid"></param>
456 /// <param name="assetUuids">Dictionary in which to record the references</param>
457 private void GetWearableAssetUuids(UUID wearableAssetUuid, IDictionary<UUID, sbyte> assetUuids)
458 {
459 AssetBase assetBase = GetAsset(wearableAssetUuid);
460
461 if (null != assetBase)
462 GetWearableAssetUuids(assetBase, assetUuids);
463 }
464
465 /// <summary>
466 /// Record the uuids referenced by the given wearable asset
467 /// </summary>
468 /// <param name="assetBase"></param>
469 /// <param name="assetUuids">Dictionary in which to record the references</param>
470 private void GetWearableAssetUuids(AssetBase assetBase, IDictionary<UUID, sbyte> assetUuids)
471 {
472 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data));
473 AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data);
474 wearableAsset.Decode();
475
476 //m_log.DebugFormat(
477 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
478
479 foreach (UUID uuid in wearableAsset.Textures.Values)
480 {
481 assetUuids[uuid] = (sbyte)AssetType.Texture;
482 }
483 }
484
485 /// <summary>
486 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
487 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
488 /// within this object).
489 /// </summary>
490 /// <param name="sceneObject"></param>
491 /// <param name="assetUuids"></param>
492 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids)
493 {
494 AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid);
495
496 if (null != sceneObjectAsset)
497 GetSceneObjectAssetUuids(sceneObjectAsset, assetUuids);
498 }
499
500 /// <summary>
501 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
502 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
503 /// within this object).
504 /// </summary>
505 /// <param name="sceneObjectAsset"></param>
506 /// <param name="assetUuids"></param>
507 private void GetSceneObjectAssetUuids(AssetBase sceneObjectAsset, IDictionary<UUID, sbyte> assetUuids)
508 {
509 string xml = Utils.BytesToString(sceneObjectAsset.Data);
510
511 CoalescedSceneObjects coa;
512 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
513 {
514 foreach (SceneObjectGroup sog in coa.Objects)
515 GatherAssetUuids(sog, assetUuids);
516 }
517 else
518 {
519 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
520
521 if (null != sog)
522 GatherAssetUuids(sog, assetUuids);
523 }
524 }
525
526 /// <summary>
527 /// Get the asset uuid associated with a gesture
528 /// </summary>
529 /// <param name="gestureUuid"></param>
530 /// <param name="assetUuids"></param>
531 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids)
532 {
533 AssetBase gestureAsset = GetAsset(gestureUuid);
534 if (null == gestureAsset)
535 return;
536
537 GetGestureAssetUuids(gestureAsset, assetUuids);
538 }
539
540 /// <summary>
541 /// Get the asset uuid associated with a gesture
542 /// </summary>
543 /// <param name="gestureAsset"></param>
544 /// <param name="assetUuids"></param>
545 private void GetGestureAssetUuids(AssetBase gestureAsset, IDictionary<UUID, sbyte> assetUuids)
546 {
547 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
548 using (StreamReader sr = new StreamReader(ms))
549 {
550 sr.ReadLine(); // Unknown (Version?)
551 sr.ReadLine(); // Unknown
552 sr.ReadLine(); // Unknown
553 sr.ReadLine(); // Name
554 sr.ReadLine(); // Comment ?
555 int count = Convert.ToInt32(sr.ReadLine()); // Item count
556
557 for (int i = 0 ; i < count ; i++)
558 {
559 string type = sr.ReadLine();
560 if (type == null)
561 break;
562 string name = sr.ReadLine();
563 if (name == null)
564 break;
565 string id = sr.ReadLine();
566 if (id == null)
567 break;
568 string unknown = sr.ReadLine();
569 if (unknown == null)
570 break;
571
572 // If it can be parsed as a UUID, it is an asset ID
573 UUID uuid;
574 if (UUID.TryParse(id, out uuid))
575 assetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
576 }
577 }
578 }
579
580 /// <summary>
581 /// Get the asset uuid's referenced in a material.
582 /// </summary>
583 private void GetMaterialAssetUuids(UUID materialUuid, IDictionary<UUID, sbyte> assetUuids)
584 {
585 AssetBase assetBase = GetAsset(materialUuid);
586 if (null == assetBase)
587 return;
588
589 GetMaterialAssetUuids(assetBase, assetUuids);
590 }
591
592 /// <summary>
593 /// Get the asset uuid's referenced in a material.
594 /// </summary> 60 /// </summary>
595 private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids) 61 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } }
596 {
597 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
598
599 UUID normMap = mat["NormMap"].AsUUID();
600 if (normMap != UUID.Zero)
601 assetUuids[normMap] = (sbyte)AssetType.Texture;
602
603 UUID specMap = mat["SpecMap"].AsUUID();
604 if (specMap != UUID.Zero)
605 assetUuids[specMap] = (sbyte)AssetType.Texture;
606 }
607 }
608
609 public class HGUuidGatherer : UuidGatherer
610 {
611 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
612
613 protected string m_assetServerURL;
614
615 public HGUuidGatherer(IAssetService assetService, string assetServerURL)
616 : base(assetService)
617 {
618 m_assetServerURL = assetServerURL;
619 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
620 m_assetServerURL = m_assetServerURL + "/";
621 }
622
623 protected override AssetBase GetAsset(UUID uuid)
624 {
625 if (string.Empty == m_assetServerURL)
626 return base.GetAsset(uuid);
627 else
628 return FetchAsset(uuid);
629 }
630
631 public AssetBase FetchAsset(UUID assetID)
632 {
633 // Test if it's already here
634 AssetBase asset = m_assetService.Get(assetID.ToString());
635 if (asset == null)
636 {
637 // It's not, so fetch it from abroad
638 asset = m_assetService.Get(m_assetServerURL + assetID.ToString());
639 if (asset != null)
640 m_log.DebugFormat("[HGUUIDGatherer]: Copied asset {0} from {1} to local asset server", assetID, m_assetServerURL);
641 else
642 m_log.DebugFormat("[HGUUIDGatherer]: Failed to fetch asset {0} from {1}", assetID, m_assetServerURL);
643 }
644 //else
645 // m_log.DebugFormat("[HGUUIDGatherer]: Asset {0} from {1} was already here", assetID, m_assetServerURL);
646
647 return asset;
648 }
649 }
650
651 /// <summary>
652 /// Gather uuids for a given entity.
653 /// </summary>
654 /// <remarks>
655 /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
656 /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
657 /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
658 /// retrieved to work out which assets it references).
659 /// </remarks>
660 public class IteratingUuidGatherer
661 {
662 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
663 62
664 /// <summary> 63 /// <summary>
665 /// Is gathering complete? 64 /// The dictionary of UUIDs gathered so far. If Complete == true then this is all the reachable UUIDs.
666 /// </summary> 65 /// </summary>
667 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } } 66 /// <value>The gathered uuids.</value>
67 public IDictionary<UUID, sbyte> GatheredUuids { get; private set; }
668 68
669 /// <summary> 69 /// <summary>
670 /// Gets the next UUID to inspect. 70 /// Gets the next UUID to inspect.
@@ -683,13 +83,20 @@ namespace OpenSim.Region.Framework.Scenes
683 83
684 protected IAssetService m_assetService; 84 protected IAssetService m_assetService;
685 85
686 protected IDictionary<UUID, sbyte> m_gatheredAssetUuids;
687
688 protected Queue<UUID> m_assetUuidsToInspect; 86 protected Queue<UUID> m_assetUuidsToInspect;
689 87
690 /// <summary> 88 /// <summary>
691 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class. 89 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
692 /// </summary> 90 /// </summary>
91 /// <remarks>In this case the collection of gathered assets will start out blank.</remarks>
92 /// <param name="assetService">
93 /// Asset service.
94 /// </param>
95 public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>()) {}
96
97 /// <summary>
98 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
99 /// </summary>
693 /// <param name="assetService"> 100 /// <param name="assetService">
694 /// Asset service. 101 /// Asset service.
695 /// </param> 102 /// </param>
@@ -697,10 +104,10 @@ namespace OpenSim.Region.Framework.Scenes
697 /// Gathered UUIDs will be collected in this dictinaory. 104 /// Gathered UUIDs will be collected in this dictinaory.
698 /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected. 105 /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
699 /// </param> 106 /// </param>
700 public IteratingUuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) 107 public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
701 { 108 {
702 m_assetService = assetService; 109 m_assetService = assetService;
703 m_gatheredAssetUuids = collector; 110 GatheredUuids = collector;
704 111
705 // FIXME: Not efficient for searching, can improve. 112 // FIXME: Not efficient for searching, can improve.
706 m_assetUuidsToInspect = new Queue<UUID>(); 113 m_assetUuidsToInspect = new Queue<UUID>();
@@ -765,13 +172,13 @@ namespace OpenSim.Region.Framework.Scenes
765 172
766 // If the prim is a sculpt then preserve this information too 173 // If the prim is a sculpt then preserve this information too
767 if (part.Shape.SculptTexture != UUID.Zero) 174 if (part.Shape.SculptTexture != UUID.Zero)
768 m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; 175 GatheredUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
769 176
770 if (part.Shape.ProjectionTextureUUID != UUID.Zero) 177 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
771 m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; 178 GatheredUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
772 179
773 if (part.CollisionSound != UUID.Zero) 180 if (part.CollisionSound != UUID.Zero)
774 m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound; 181 GatheredUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
775 182
776 if (part.ParticleSystem.Length > 0) 183 if (part.ParticleSystem.Length > 0)
777 { 184 {
@@ -779,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
779 { 186 {
780 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); 187 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
781 if (ps.Texture != UUID.Zero) 188 if (ps.Texture != UUID.Zero)
782 m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture; 189 GatheredUuids[ps.Texture] = (sbyte)AssetType.Texture;
783 } 190 }
784 catch (Exception) 191 catch (Exception)
785 { 192 {
@@ -798,7 +205,7 @@ namespace OpenSim.Region.Framework.Scenes
798 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", 205 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
799 // tii.Name, tii.Type, part.Name, part.UUID); 206 // tii.Name, tii.Type, part.Name, part.UUID);
800 207
801 if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID)) 208 if (!GatheredUuids.ContainsKey(tii.AssetID))
802 AddForInspection(tii.AssetID, (sbyte)tii.Type); 209 AddForInspection(tii.AssetID, (sbyte)tii.Type);
803 } 210 }
804 211
@@ -865,7 +272,7 @@ namespace OpenSim.Region.Framework.Scenes
865 private void GetAssetUuids(UUID assetUuid) 272 private void GetAssetUuids(UUID assetUuid)
866 { 273 {
867 // avoid infinite loops 274 // avoid infinite loops
868 if (m_gatheredAssetUuids.ContainsKey(assetUuid)) 275 if (GatheredUuids.ContainsKey(assetUuid))
869 return; 276 return;
870 277
871 try 278 try
@@ -875,7 +282,7 @@ namespace OpenSim.Region.Framework.Scenes
875 if (null != assetBase) 282 if (null != assetBase)
876 { 283 {
877 sbyte assetType = assetBase.Type; 284 sbyte assetType = assetBase.Type;
878 m_gatheredAssetUuids[assetUuid] = assetType; 285 GatheredUuids[assetUuid] = assetType;
879 286
880 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 287 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
881 { 288 {
@@ -915,29 +322,15 @@ namespace OpenSim.Region.Framework.Scenes
915 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered 322 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
916 try 323 try
917 { 324 {
918 m_gatheredAssetUuids[assetUuid] = assetType; 325 GatheredUuids[assetUuid] = assetType;
919 326
920 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 327 if ((sbyte)AssetType.Bodypart == assetType
921 { 328 || (sbyte)AssetType.Clothing == assetType
922 AddForInspection(assetUuid); 329 || (sbyte)AssetType.Gesture == assetType
923 } 330 || (sbyte)AssetType.Notecard == assetType
924 else if ((sbyte)AssetType.Gesture == assetType) 331 || (sbyte)AssetType.LSLText == assetType
925 { 332 || (sbyte)OpenSimAssetType.Material == assetType
926 AddForInspection(assetUuid); 333 || (sbyte)AssetType.Object == assetType)
927 }
928 else if ((sbyte)AssetType.Notecard == assetType)
929 {
930 AddForInspection(assetUuid);
931 }
932 else if ((sbyte)AssetType.LSLText == assetType)
933 {
934 AddForInspection(assetUuid);
935 }
936 else if ((sbyte)OpenSimAssetType.Material == assetType)
937 {
938 AddForInspection(assetUuid);
939 }
940 else if ((sbyte)AssetType.Object == assetType)
941 { 334 {
942 AddForInspection(assetUuid); 335 AddForInspection(assetUuid);
943 } 336 }
@@ -956,7 +349,7 @@ namespace OpenSim.Region.Framework.Scenes
956 /// </summary> 349 /// </summary>
957 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture) 350 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture)
958 { 351 {
959 m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture; 352 GatheredUuids[texture.TextureID] = (sbyte)AssetType.Texture;
960 353
961 if (texture.MaterialID != UUID.Zero) 354 if (texture.MaterialID != UUID.Zero)
962 AddForInspection(texture.MaterialID); 355 AddForInspection(texture.MaterialID);
@@ -1003,7 +396,7 @@ namespace OpenSim.Region.Framework.Scenes
1003 UUID normalMapId = mat["NormMap"].AsUUID(); 396 UUID normalMapId = mat["NormMap"].AsUUID();
1004 if (normalMapId != UUID.Zero) 397 if (normalMapId != UUID.Zero)
1005 { 398 {
1006 m_gatheredAssetUuids[normalMapId] = (sbyte)AssetType.Texture; 399 GatheredUuids[normalMapId] = (sbyte)AssetType.Texture;
1007 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString()); 400 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
1008 } 401 }
1009 } 402 }
@@ -1012,7 +405,7 @@ namespace OpenSim.Region.Framework.Scenes
1012 UUID specularMapId = mat["SpecMap"].AsUUID(); 405 UUID specularMapId = mat["SpecMap"].AsUUID();
1013 if (specularMapId != UUID.Zero) 406 if (specularMapId != UUID.Zero)
1014 { 407 {
1015 m_gatheredAssetUuids[specularMapId] = (sbyte)AssetType.Texture; 408 GatheredUuids[specularMapId] = (sbyte)AssetType.Texture;
1016 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString()); 409 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
1017 } 410 }
1018 } 411 }
@@ -1048,17 +441,17 @@ namespace OpenSim.Region.Framework.Scenes
1048 { 441 {
1049 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); 442 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
1050 443
1051 string script = Utils.BytesToString(textAsset.Data); 444 string text = Utils.BytesToString(textAsset.Data);
1052 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); 445// m_log.DebugFormat("[UUID GATHERER]: Text {0}", text);
1053 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); 446 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(text);
1054 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); 447// m_log.DebugFormat("[UUID GATHERER]: Found {0} matches in text", uuidMatches.Count);
1055 448
1056 foreach (Match uuidMatch in uuidMatches) 449 foreach (Match uuidMatch in uuidMatches)
1057 { 450 {
1058 UUID uuid = new UUID(uuidMatch.Value); 451 UUID uuid = new UUID(uuidMatch.Value);
1059 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); 452// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid);
1060 453
1061 AddForInspection(uuid); 454 GatheredUuids[uuid] = (sbyte)AssetType.Unknown;
1062 } 455 }
1063 } 456 }
1064 457
@@ -1076,7 +469,7 @@ namespace OpenSim.Region.Framework.Scenes
1076 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); 469 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
1077 470
1078 foreach (UUID uuid in wearableAsset.Textures.Values) 471 foreach (UUID uuid in wearableAsset.Textures.Values)
1079 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Texture; 472 GatheredUuids[uuid] = (sbyte)AssetType.Texture;
1080 } 473 }
1081 474
1082 /// <summary> 475 /// <summary>
@@ -1138,7 +531,7 @@ namespace OpenSim.Region.Framework.Scenes
1138 // If it can be parsed as a UUID, it is an asset ID 531 // If it can be parsed as a UUID, it is an asset ID
1139 UUID uuid; 532 UUID uuid;
1140 if (UUID.TryParse(id, out uuid)) 533 if (UUID.TryParse(id, out uuid))
1141 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important 534 GatheredUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
1142 } 535 }
1143 } 536 }
1144 } 537 }
@@ -1152,21 +545,24 @@ namespace OpenSim.Region.Framework.Scenes
1152 545
1153 UUID normMap = mat["NormMap"].AsUUID(); 546 UUID normMap = mat["NormMap"].AsUUID();
1154 if (normMap != UUID.Zero) 547 if (normMap != UUID.Zero)
1155 m_gatheredAssetUuids[normMap] = (sbyte)AssetType.Texture; 548 GatheredUuids[normMap] = (sbyte)AssetType.Texture;
1156 549
1157 UUID specMap = mat["SpecMap"].AsUUID(); 550 UUID specMap = mat["SpecMap"].AsUUID();
1158 if (specMap != UUID.Zero) 551 if (specMap != UUID.Zero)
1159 m_gatheredAssetUuids[specMap] = (sbyte)AssetType.Texture; 552 GatheredUuids[specMap] = (sbyte)AssetType.Texture;
1160 } 553 }
1161 } 554 }
1162 555
1163 public class IteratingHGUuidGatherer : IteratingUuidGatherer 556 public class HGUuidGatherer : UuidGatherer
1164 { 557 {
1165 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 558 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1166 559
1167 protected string m_assetServerURL; 560 protected string m_assetServerURL;
1168 561
1169 public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector) 562 public HGUuidGatherer(IAssetService assetService, string assetServerURL)
563 : this(assetService, assetServerURL, new Dictionary<UUID, sbyte>()) {}
564
565 public HGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector)
1170 : base(assetService, collector) 566 : base(assetService, collector)
1171 { 567 {
1172 m_assetServerURL = assetServerURL; 568 m_assetServerURL = assetServerURL;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index f67f613..2f9bb1e 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -426,10 +426,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
426 cdl.AddRow("Assets", ""); 426 cdl.AddRow("Assets", "");
427 sb.Append(cdl.ToString()); 427 sb.Append(cdl.ToString());
428 428
429 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); 429 uuidGatherer.AddForInspection(wi.AssetID);
430 uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids); 430 uuidGatherer.GatherAll();
431 string[] assetStrings 431 string[] assetStrings
432 = Array.ConvertAll<UUID, string>(assetUuids.Keys.ToArray(), u => u.ToString()); 432 = Array.ConvertAll<UUID, string>(uuidGatherer.GatheredUuids.Keys.ToArray(), u => u.ToString());
433 433
434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); 434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings);
435 435
@@ -440,7 +440,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
440 cdt.AddColumn("Found", 5); 440 cdt.AddColumn("Found", 5);
441 441
442 for (int k = 0; k < existChecks.Length; k++) 442 for (int k = 0; k < existChecks.Length; k++)
443 cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no"); 443 cdt.AddRow(
444 (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])],
445 assetStrings[k], existChecks[k] ? "yes" : "no");
444 446
445 sb.Append(cdt.ToString()); 447 sb.Append(cdt.ToString());
446 sb.Append("\n"); 448 sb.Append("\n");