aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/Framework/Scenes/UuidGatherer.cs
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs604
1 files changed, 400 insertions, 204 deletions
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index e238d01..9ec4e1d 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -34,9 +34,11 @@ using System.Threading;
34using log4net; 34using log4net;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenMetaverse.Assets; 36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Region.Framework.Scenes.Serialization; 39using OpenSim.Region.Framework.Scenes.Serialization;
39using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using OpenSimAssetType = OpenSim.Framework.SLUtil.OpenSimAssetType;
40 42
41namespace OpenSim.Region.Framework.Scenes 43namespace OpenSim.Region.Framework.Scenes
42{ 44{
@@ -53,75 +55,81 @@ namespace OpenSim.Region.Framework.Scenes
53 { 55 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 57
58 /// <summary>
59 /// Is gathering complete?
60 /// </summary>
61 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } }
62
63 /// <summary>
64 /// The dictionary of UUIDs gathered so far. If Complete == true then this is all the reachable UUIDs.
65 /// </summary>
66 /// <value>The gathered uuids.</value>
67 public IDictionary<UUID, sbyte> GatheredUuids { get; private set; }
68
69 /// <summary>
70 /// Gets the next UUID to inspect.
71 /// </summary>
72 /// <value>If there is no next UUID then returns null</value>
73 public UUID? NextUuidToInspect
74 {
75 get
76 {
77 if (Complete)
78 return null;
79 else
80 return m_assetUuidsToInspect.Peek();
81 }
82 }
83
56 protected IAssetService m_assetService; 84 protected IAssetService m_assetService;
57 85
58// /// <summary> 86 protected Queue<UUID> m_assetUuidsToInspect;
59// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate 87
60// /// asset was found by the asset service. 88 /// <summary>
61// /// </summary> 89 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
62// private AssetBase m_requestedObjectAsset; 90 /// </summary>
63// 91 /// <remarks>In this case the collection of gathered assets will start out blank.</remarks>
64// /// <summary> 92 /// <param name="assetService">
65// /// Signal whether we are currently waiting for the asset service to deliver an asset. 93 /// Asset service.
66// /// </summary> 94 /// </param>
67// private bool m_waitingForObjectAsset; 95 public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>()) {}
68 96
69 public UuidGatherer(IAssetService assetService) 97 /// <summary>
98 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
99 /// </summary>
100 /// <param name="assetService">
101 /// Asset service.
102 /// </param>
103 /// <param name="collector">
104 /// Gathered UUIDs will be collected in this dictinaory.
105 /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
106 /// </param>
107 public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
70 { 108 {
71 m_assetService = assetService; 109 m_assetService = assetService;
110 GatheredUuids = collector;
111
112 // FIXME: Not efficient for searching, can improve.
113 m_assetUuidsToInspect = new Queue<UUID>();
72 } 114 }
73 115
74 /// <summary> 116 /// <summary>
75 /// Gather all the asset uuids associated with the asset referenced by a given uuid 117 /// Adds the asset uuid for inspection during the gathering process.
76 /// </summary> 118 /// </summary>
77 /// <remarks> 119 /// <returns><c>true</c>, if for inspection was added, <c>false</c> otherwise.</returns>
78 /// This includes both those directly associated with 120 /// <param name="uuid">UUID.</param>
79 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 121 public bool AddForInspection(UUID uuid)
80 /// within this object).
81 /// </remarks>
82 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
83 /// <param name="assetType">The type of the asset for the uuid given</param>
84 /// <param name="assetUuids">The assets gathered</param>
85 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids)
86 { 122 {
87 // avoid infinite loops 123 if (m_assetUuidsToInspect.Contains(uuid))
88 if (assetUuids.ContainsKey(assetUuid)) 124 return false;
89 return;
90 125
91 try 126// m_log.DebugFormat("[UUID GATHERER]: Adding asset {0} for inspection", uuid);
92 { 127
93 assetUuids[assetUuid] = assetType; 128 m_assetUuidsToInspect.Enqueue(uuid);
94
95 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType)
96 {
97 GetWearableAssetUuids(assetUuid, assetUuids);
98 }
99 else if (AssetType.Gesture == assetType)
100 {
101 GetGestureAssetUuids(assetUuid, assetUuids);
102 }
103 else if (AssetType.Notecard == assetType)
104 {
105 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
106 }
107 else if (AssetType.LSLText == assetType)
108 {
109 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
110 }
111 else if (AssetType.Object == assetType)
112 {
113 GetSceneObjectAssetUuids(assetUuid, assetUuids);
114 }
115 }
116 catch (Exception)
117 {
118 m_log.ErrorFormat(
119 "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
120 assetUuid, assetType);
121 throw;
122 }
123 }
124 129
130 return true;
131 }
132
125 /// <summary> 133 /// <summary>
126 /// Gather all the asset uuids associated with a given object. 134 /// Gather all the asset uuids associated with a given object.
127 /// </summary> 135 /// </summary>
@@ -131,19 +139,18 @@ namespace OpenSim.Region.Framework.Scenes
131 /// within this object). 139 /// within this object).
132 /// </remarks> 140 /// </remarks>
133 /// <param name="sceneObject">The scene object for which to gather assets</param> 141 /// <param name="sceneObject">The scene object for which to gather assets</param>
134 /// <param name="assetUuids">The assets gathered</param> 142 public void AddForInspection(SceneObjectGroup sceneObject)
135 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)
136 { 143 {
137// m_log.DebugFormat( 144 // m_log.DebugFormat(
138// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); 145 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
139 146
140 SceneObjectPart[] parts = sceneObject.Parts; 147 SceneObjectPart[] parts = sceneObject.Parts;
141 for (int i = 0; i < parts.Length; i++) 148 for (int i = 0; i < parts.Length; i++)
142 { 149 {
143 SceneObjectPart part = parts[i]; 150 SceneObjectPart part = parts[i];
144 151
145// m_log.DebugFormat( 152 // m_log.DebugFormat(
146// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); 153 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
147 154
148 try 155 try
149 { 156 {
@@ -152,7 +159,7 @@ namespace OpenSim.Region.Framework.Scenes
152 { 159 {
153 // Get the prim's default texture. This will be used for faces which don't have their own texture 160 // Get the prim's default texture. This will be used for faces which don't have their own texture
154 if (textureEntry.DefaultTexture != null) 161 if (textureEntry.DefaultTexture != null)
155 assetUuids[textureEntry.DefaultTexture.TextureID] = AssetType.Texture; 162 RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
156 163
157 if (textureEntry.FaceTextures != null) 164 if (textureEntry.FaceTextures != null)
158 { 165 {
@@ -160,27 +167,59 @@ namespace OpenSim.Region.Framework.Scenes
160 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) 167 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
161 { 168 {
162 if (texture != null) 169 if (texture != null)
163 assetUuids[texture.TextureID] = AssetType.Texture; 170 RecordTextureEntryAssetUuids(texture);
164 } 171 }
165 } 172 }
166 } 173 }
167 174
168 // If the prim is a sculpt then preserve this information too 175 // If the prim is a sculpt then preserve this information too
169 if (part.Shape.SculptTexture != UUID.Zero) 176 if (part.Shape.SculptTexture != UUID.Zero)
170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture; 177 GatheredUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
171 178
179 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
180 GatheredUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
181
182 if (part.CollisionSound != UUID.Zero)
183 GatheredUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
184
185 if (part.ParticleSystem.Length > 0)
186 {
187 try
188 {
189 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
190 if (ps.Texture != UUID.Zero)
191 GatheredUuids[ps.Texture] = (sbyte)AssetType.Texture;
192 }
193 catch (Exception)
194 {
195 m_log.WarnFormat(
196 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
197 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
198 }
199 }
200
172 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 201 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
173 202
174 // Now analyze this prim's inventory items to preserve all the uuids that they reference 203 // Now analyze this prim's inventory items to preserve all the uuids that they reference
175 foreach (TaskInventoryItem tii in taskDictionary.Values) 204 foreach (TaskInventoryItem tii in taskDictionary.Values)
176 { 205 {
177// m_log.DebugFormat( 206 // m_log.DebugFormat(
178// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", 207 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
179// tii.Name, tii.Type, part.Name, part.UUID); 208 // tii.Name, tii.Type, part.Name, part.UUID);
180 209
181 if (!assetUuids.ContainsKey(tii.AssetID)) 210 if (!GatheredUuids.ContainsKey(tii.AssetID))
182 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); 211 AddForInspection(tii.AssetID, (sbyte)tii.Type);
183 } 212 }
213
214 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
215 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
216 // inventory transfer. There needs to be a way for a module to register a method without assuming a
217 // Scene.EventManager is present.
218 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
219
220
221 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
222 RecordMaterialsUuids(part);
184 } 223 }
185 catch (Exception e) 224 catch (Exception e)
186 { 225 {
@@ -191,179 +230,334 @@ namespace OpenSim.Region.Framework.Scenes
191 } 230 }
192 } 231 }
193 } 232 }
194
195// /// <summary>
196// /// The callback made when we request the asset for an object from the asset service.
197// /// </summary>
198// private void AssetReceived(string id, Object sender, AssetBase asset)
199// {
200// lock (this)
201// {
202// m_requestedObjectAsset = asset;
203// m_waitingForObjectAsset = false;
204// Monitor.Pulse(this);
205// }
206// }
207 233
208 /// <summary> 234 /// <summary>
209 /// Get an asset synchronously, potentially using an asynchronous callback. If the 235 /// Gathers the next set of assets returned by the next uuid to get from the asset service.
210 /// asynchronous callback is used, we will wait for it to complete.
211 /// </summary> 236 /// </summary>
212 /// <param name="uuid"></param> 237 /// <returns>false if gathering is already complete, true otherwise</returns>
213 /// <returns></returns> 238 public bool GatherNext()
214 protected virtual AssetBase GetAsset(UUID uuid)
215 { 239 {
216 return m_assetService.Get(uuid.ToString()); 240 if (Complete)
241 return false;
242
243 UUID nextToInspect = m_assetUuidsToInspect.Dequeue();
244
245// m_log.DebugFormat("[UUID GATHERER]: Inspecting asset {0}", nextToInspect);
246
247 GetAssetUuids(nextToInspect);
217 248
218 // XXX: Switching to do this synchronously where the call was async before but we always waited for it 249 return true;
219 // to complete anyway!
220// m_waitingForObjectAsset = true;
221// m_assetCache.Get(uuid.ToString(), this, AssetReceived);
222//
223// // The asset cache callback can either
224// //
225// // 1. Complete on the same thread (if the asset is already in the cache) or
226// // 2. Come in via a different thread (if we need to go fetch it).
227// //
228// // The code below handles both these alternatives.
229// lock (this)
230// {
231// if (m_waitingForObjectAsset)
232// {
233// Monitor.Wait(this);
234// m_waitingForObjectAsset = false;
235// }
236// }
237//
238// return m_requestedObjectAsset;
239 } 250 }
240 251
241 /// <summary> 252 /// <summary>
242 /// Record the asset uuids embedded within the given script. 253 /// Gathers all remaining asset UUIDS no matter how many calls are required to the asset service.
243 /// </summary> 254 /// </summary>
244 /// <param name="scriptUuid"></param> 255 /// <returns>false if gathering is already complete, true otherwise</returns>
245 /// <param name="assetUuids">Dictionary in which to record the references</param> 256 public bool GatherAll()
246 private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, AssetType> assetUuids)
247 { 257 {
248// m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); 258 if (Complete)
259 return false;
249 260
250 AssetBase embeddingAsset = GetAsset(embeddingAssetId); 261 while (GatherNext());
251 262
252 if (null != embeddingAsset) 263 return true;
253 { 264 }
254 string script = Utils.BytesToString(embeddingAsset.Data);
255// m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
256 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
257// m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
258 265
259 foreach (Match uuidMatch in uuidMatches) 266 /// <summary>
267 /// Gather all the asset uuids associated with the asset referenced by a given uuid
268 /// </summary>
269 /// <remarks>
270 /// This includes both those directly associated with
271 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
272 /// within this object).
273 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
274 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
275 /// is of a type which is known not to reference any other assets
276 /// </remarks>
277 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
278 private void GetAssetUuids(UUID assetUuid)
279 {
280 // avoid infinite loops
281 if (GatheredUuids.ContainsKey(assetUuid))
282 return;
283
284 try
285 {
286 AssetBase assetBase = GetAsset(assetUuid);
287
288 if (null != assetBase)
260 { 289 {
261 UUID uuid = new UUID(uuidMatch.Value); 290 sbyte assetType = assetBase.Type;
262// m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); 291 GatheredUuids[assetUuid] = assetType;
292
293 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
294 {
295 RecordWearableAssetUuids(assetBase);
296 }
297 else if ((sbyte)AssetType.Gesture == assetType)
298 {
299 RecordGestureAssetUuids(assetBase);
300 }
301 else if ((sbyte)AssetType.Notecard == assetType)
302 {
303 RecordTextEmbeddedAssetUuids(assetBase);
304 }
305 else if ((sbyte)AssetType.LSLText == assetType)
306 {
307 RecordTextEmbeddedAssetUuids(assetBase);
308 }
309 else if ((sbyte)OpenSimAssetType.Material == assetType)
310 {
311 RecordMaterialAssetUuids(assetBase);
312 }
313 else if ((sbyte)AssetType.Object == assetType)
314 {
315 RecordSceneObjectAssetUuids(assetBase);
316 }
317 }
318 }
319 catch (Exception)
320 {
321 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
322 throw;
323 }
324 }
263 325
264 // Assume AssetIDs embedded are textures. 326 private void AddForInspection(UUID assetUuid, sbyte assetType)
265 assetUuids[uuid] = AssetType.Texture; 327 {
328 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
329 try
330 {
331 if ((sbyte)AssetType.Bodypart == assetType
332 || (sbyte)AssetType.Clothing == assetType
333 || (sbyte)AssetType.Gesture == assetType
334 || (sbyte)AssetType.Notecard == assetType
335 || (sbyte)AssetType.LSLText == assetType
336 || (sbyte)OpenSimAssetType.Material == assetType
337 || (sbyte)AssetType.Object == assetType)
338 {
339 AddForInspection(assetUuid);
340 }
341 else
342 {
343 GatheredUuids[assetUuid] = assetType;
266 } 344 }
267 } 345 }
346 catch (Exception)
347 {
348 m_log.ErrorFormat(
349 "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
350 assetUuid, assetType);
351 throw;
352 }
268 } 353 }
269 354
270 /// <summary> 355 /// <summary>
271 /// Record the uuids referenced by the given wearable asset 356 /// Collect all the asset uuids found in one face of a Texture Entry.
272 /// </summary> 357 /// </summary>
273 /// <param name="wearableAssetUuid"></param> 358 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture)
274 /// <param name="assetUuids">Dictionary in which to record the references</param>
275 private void GetWearableAssetUuids(UUID wearableAssetUuid, IDictionary<UUID, AssetType> assetUuids)
276 { 359 {
277 AssetBase assetBase = GetAsset(wearableAssetUuid); 360 GatheredUuids[texture.TextureID] = (sbyte)AssetType.Texture;
278 361
279 if (null != assetBase) 362 if (texture.MaterialID != UUID.Zero)
363 AddForInspection(texture.MaterialID);
364 }
365
366 /// <summary>
367 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
368 /// stored in legacy format in part.DynAttrs
369 /// </summary>
370 /// <param name="part"></param>
371 private void RecordMaterialsUuids(SceneObjectPart part)
372 {
373 // scan thru the dynAttrs map of this part for any textures used as materials
374 OSD osdMaterials = null;
375
376 lock (part.DynAttrs)
280 { 377 {
281 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); 378 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
282 AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data);
283 wearableAsset.Decode();
284
285 //m_log.DebugFormat(
286 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
287
288 foreach (UUID uuid in wearableAsset.Textures.Values)
289 { 379 {
290 assetUuids[uuid] = AssetType.Texture; 380 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
381
382 if (materialsStore == null)
383 return;
384
385 materialsStore.TryGetValue("Materials", out osdMaterials);
386 }
387
388 if (osdMaterials != null)
389 {
390 //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
391
392 if (osdMaterials is OSDArray)
393 {
394 OSDArray matsArr = osdMaterials as OSDArray;
395 foreach (OSDMap matMap in matsArr)
396 {
397 try
398 {
399 if (matMap.ContainsKey("Material"))
400 {
401 OSDMap mat = matMap["Material"] as OSDMap;
402 if (mat.ContainsKey("NormMap"))
403 {
404 UUID normalMapId = mat["NormMap"].AsUUID();
405 if (normalMapId != UUID.Zero)
406 {
407 GatheredUuids[normalMapId] = (sbyte)AssetType.Texture;
408 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
409 }
410 }
411 if (mat.ContainsKey("SpecMap"))
412 {
413 UUID specularMapId = mat["SpecMap"].AsUUID();
414 if (specularMapId != UUID.Zero)
415 {
416 GatheredUuids[specularMapId] = (sbyte)AssetType.Texture;
417 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
418 }
419 }
420 }
421
422 }
423 catch (Exception e)
424 {
425 m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message);
426 }
427 }
428 }
291 } 429 }
292 } 430 }
293 } 431 }
294 432
295 /// <summary> 433 /// <summary>
434 /// Get an asset synchronously, potentially using an asynchronous callback. If the
435 /// asynchronous callback is used, we will wait for it to complete.
436 /// </summary>
437 /// <param name="uuid"></param>
438 /// <returns></returns>
439 protected virtual AssetBase GetAsset(UUID uuid)
440 {
441 return m_assetService.Get(uuid.ToString());
442 }
443
444 /// <summary>
445 /// Record the asset uuids embedded within the given text (e.g. a script).
446 /// </summary>
447 /// <param name="textAsset"></param>
448 private void RecordTextEmbeddedAssetUuids(AssetBase textAsset)
449 {
450 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
451
452 string text = Utils.BytesToString(textAsset.Data);
453// m_log.DebugFormat("[UUID GATHERER]: Text {0}", text);
454 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(text);
455// m_log.DebugFormat("[UUID GATHERER]: Found {0} matches in text", uuidMatches.Count);
456
457 foreach (Match uuidMatch in uuidMatches)
458 {
459 UUID uuid = new UUID(uuidMatch.Value);
460// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid);
461
462 AddForInspection(uuid);
463 }
464 }
465
466 /// <summary>
467 /// Record the uuids referenced by the given wearable asset
468 /// </summary>
469 /// <param name="assetBase"></param>
470 private void RecordWearableAssetUuids(AssetBase assetBase)
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 GatheredUuids[uuid] = (sbyte)AssetType.Texture;
481 }
482
483 /// <summary>
296 /// Get all the asset uuids associated with a given object. This includes both those directly associated with 484 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
297 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 485 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
298 /// within this object). 486 /// within this object).
299 /// </summary> 487 /// </summary>
300 /// <param name="sceneObject"></param> 488 /// <param name="sceneObjectAsset"></param>
301 /// <param name="assetUuids"></param> 489 private void RecordSceneObjectAssetUuids(AssetBase sceneObjectAsset)
302 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, AssetType> assetUuids)
303 { 490 {
304 AssetBase objectAsset = GetAsset(sceneObjectUuid); 491 string xml = Utils.BytesToString(sceneObjectAsset.Data);
305 492
306 if (null != objectAsset) 493 CoalescedSceneObjects coa;
494 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
307 { 495 {
308 string xml = Utils.BytesToString(objectAsset.Data); 496 foreach (SceneObjectGroup sog in coa.Objects)
309 497 AddForInspection(sog);
310 CoalescedSceneObjects coa; 498 }
311 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) 499 else
312 { 500 {
313 foreach (SceneObjectGroup sog in coa.Objects) 501 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
314 GatherAssetUuids(sog, assetUuids); 502
315 } 503 if (null != sog)
316 else 504 AddForInspection(sog);
505 }
506 }
507
508 /// <summary>
509 /// Get the asset uuid associated with a gesture
510 /// </summary>
511 /// <param name="gestureAsset"></param>
512 private void RecordGestureAssetUuids(AssetBase gestureAsset)
513 {
514 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
515 using (StreamReader sr = new StreamReader(ms))
516 {
517 sr.ReadLine(); // Unknown (Version?)
518 sr.ReadLine(); // Unknown
519 sr.ReadLine(); // Unknown
520 sr.ReadLine(); // Name
521 sr.ReadLine(); // Comment ?
522 int count = Convert.ToInt32(sr.ReadLine()); // Item count
523
524 for (int i = 0 ; i < count ; i++)
317 { 525 {
318 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); 526 string type = sr.ReadLine();
319 527 if (type == null)
320 if (null != sog) 528 break;
321 GatherAssetUuids(sog, assetUuids); 529 string name = sr.ReadLine();
530 if (name == null)
531 break;
532 string id = sr.ReadLine();
533 if (id == null)
534 break;
535 string unknown = sr.ReadLine();
536 if (unknown == null)
537 break;
538
539 // If it can be parsed as a UUID, it is an asset ID
540 UUID uuid;
541 if (UUID.TryParse(id, out uuid))
542 GatheredUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
322 } 543 }
323 } 544 }
324 } 545 }
325 546
326 /// <summary> 547 /// <summary>
327 /// Get the asset uuid associated with a gesture 548 /// Get the asset uuid's referenced in a material.
328 /// </summary> 549 /// </summary>
329 /// <param name="gestureUuid"></param> 550 private void RecordMaterialAssetUuids(AssetBase materialAsset)
330 /// <param name="assetUuids"></param>
331 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, AssetType> assetUuids)
332 { 551 {
333 AssetBase assetBase = GetAsset(gestureUuid); 552 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
334 if (null == assetBase)
335 return;
336
337 MemoryStream ms = new MemoryStream(assetBase.Data);
338 StreamReader sr = new StreamReader(ms);
339 553
340 sr.ReadLine(); // Unknown (Version?) 554 UUID normMap = mat["NormMap"].AsUUID();
341 sr.ReadLine(); // Unknown 555 if (normMap != UUID.Zero)
342 sr.ReadLine(); // Unknown 556 GatheredUuids[normMap] = (sbyte)AssetType.Texture;
343 sr.ReadLine(); // Name
344 sr.ReadLine(); // Comment ?
345 int count = Convert.ToInt32(sr.ReadLine()); // Item count
346 557
347 for (int i = 0 ; i < count ; i++) 558 UUID specMap = mat["SpecMap"].AsUUID();
348 { 559 if (specMap != UUID.Zero)
349 string type = sr.ReadLine(); 560 GatheredUuids[specMap] = (sbyte)AssetType.Texture;
350 if (type == null)
351 break;
352 string name = sr.ReadLine();
353 if (name == null)
354 break;
355 string id = sr.ReadLine();
356 if (id == null)
357 break;
358 string unknown = sr.ReadLine();
359 if (unknown == null)
360 break;
361
362 // If it can be parsed as a UUID, it is an asset ID
363 UUID uuid;
364 if (UUID.TryParse(id, out uuid))
365 assetUuids[uuid] = AssetType.Animation;
366 }
367 } 561 }
368 } 562 }
369 563
@@ -374,7 +568,10 @@ namespace OpenSim.Region.Framework.Scenes
374 protected string m_assetServerURL; 568 protected string m_assetServerURL;
375 569
376 public HGUuidGatherer(IAssetService assetService, string assetServerURL) 570 public HGUuidGatherer(IAssetService assetService, string assetServerURL)
377 : base(assetService) 571 : this(assetService, assetServerURL, new Dictionary<UUID, sbyte>()) {}
572
573 public HGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector)
574 : base(assetService, collector)
378 { 575 {
379 m_assetServerURL = assetServerURL; 576 m_assetServerURL = assetServerURL;
380 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("=")) 577 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
@@ -391,7 +588,6 @@ namespace OpenSim.Region.Framework.Scenes
391 588
392 public AssetBase FetchAsset(UUID assetID) 589 public AssetBase FetchAsset(UUID assetID)
393 { 590 {
394
395 // Test if it's already here 591 // Test if it's already here
396 AssetBase asset = m_assetService.Get(assetID.ToString()); 592 AssetBase asset = m_assetService.Get(assetID.ToString());
397 if (asset == null) 593 if (asset == null)