aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2015-01-08 20:21:40 +0000
committerJustin Clark-Casey (justincc)2015-01-08 20:21:40 +0000
commit08606ae409b400b6f9b83006ed04826eede8a9c7 (patch)
treeb11e1ebfa99dfda28aa3df22041c6e3d167491ce /OpenSim/Region/Framework/Scenes/UuidGatherer.cs
parentCommented out clear_registry_ because (1) it isn't clearing up anything anymo... (diff)
downloadopensim-SC_OLD-08606ae409b400b6f9b83006ed04826eede8a9c7.zip
opensim-SC_OLD-08606ae409b400b6f9b83006ed04826eede8a9c7.tar.gz
opensim-SC_OLD-08606ae409b400b6f9b83006ed04826eede8a9c7.tar.bz2
opensim-SC_OLD-08606ae409b400b6f9b83006ed04826eede8a9c7.tar.xz
Make the IteratingUuidGatherer the only UuidGatherer.
This UUID gatherer provides a superset of the previous gatherer's functionality as it also allows the caller to control gathering iterations for load purposes.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/UuidGatherer.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs704
1 files changed, 50 insertions, 654 deletions
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;