diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 222 |
1 files changed, 158 insertions, 64 deletions
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index d07cc6a..20ff5b5 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -72,6 +72,67 @@ namespace OpenSim.Region.Framework.Scenes | |||
72 | { | 72 | { |
73 | m_assetService = assetService; | 73 | m_assetService = assetService; |
74 | } | 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 | } | ||
75 | 136 | ||
76 | /// <summary> | 137 | /// <summary> |
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | 138 | /// Gather all the asset uuids associated with the asset referenced by a given uuid |
@@ -246,19 +307,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
246 | } | 307 | } |
247 | } | 308 | } |
248 | 309 | ||
249 | // /// <summary> | ||
250 | // /// The callback made when we request the asset for an object from the asset service. | ||
251 | // /// </summary> | ||
252 | // private void AssetReceived(string id, Object sender, AssetBase asset) | ||
253 | // { | ||
254 | // lock (this) | ||
255 | // { | ||
256 | // m_requestedObjectAsset = asset; | ||
257 | // m_waitingForObjectAsset = false; | ||
258 | // Monitor.Pulse(this); | ||
259 | // } | ||
260 | // } | ||
261 | |||
262 | /// <summary> | 310 | /// <summary> |
263 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps | 311 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps |
264 | /// stored in legacy format in part.DynAttrs | 312 | /// stored in legacy format in part.DynAttrs |
@@ -362,32 +410,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
362 | } | 410 | } |
363 | 411 | ||
364 | /// <summary> | 412 | /// <summary> |
365 | /// Record the asset uuids embedded within the given script. | 413 | /// Record the asset uuids embedded within the given text (e.g. a script). |
366 | /// </summary> | 414 | /// </summary> |
367 | /// <param name="scriptUuid"></param> | 415 | /// <param name="textAssetUuid"></param> |
368 | /// <param name="assetUuids">Dictionary in which to record the references</param> | 416 | /// <param name="assetUuids">Dictionary in which to record the references</param> |
369 | private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids) | 417 | private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids) |
370 | { | 418 | { |
371 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | 419 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); |
372 | 420 | ||
373 | AssetBase embeddingAsset = GetAsset(embeddingAssetId); | 421 | AssetBase textAsset = GetAsset(textAssetUuid); |
374 | 422 | ||
375 | if (null != embeddingAsset) | 423 | if (null != textAsset) |
376 | { | 424 | GetTextEmbeddedAssetUuids(textAsset, assetUuids); |
377 | string script = Utils.BytesToString(embeddingAsset.Data); | 425 | } |
378 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); | ||
379 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); | ||
380 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); | ||
381 | 426 | ||
382 | foreach (Match uuidMatch in uuidMatches) | 427 | /// <summary> |
383 | { | 428 | /// Record the asset uuids embedded within the given text (e.g. a script). |
384 | UUID uuid = new UUID(uuidMatch.Value); | 429 | /// </summary> |
385 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | 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); | ||
386 | 435 | ||
387 | // Embedded asset references (if not false positives) could be for many types of asset, so we will | 436 | string script = Utils.BytesToString(textAsset.Data); |
388 | // label these as unknown. | 437 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); |
389 | assetUuids[uuid] = (sbyte)AssetType.Unknown; | 438 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); |
390 | } | 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; | ||
391 | } | 449 | } |
392 | } | 450 | } |
393 | 451 | ||
@@ -401,18 +459,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | AssetBase assetBase = GetAsset(wearableAssetUuid); | 459 | AssetBase assetBase = GetAsset(wearableAssetUuid); |
402 | 460 | ||
403 | if (null != assetBase) | 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) | ||
404 | { | 480 | { |
405 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | 481 | assetUuids[uuid] = (sbyte)AssetType.Texture; |
406 | AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data); | ||
407 | wearableAsset.Decode(); | ||
408 | |||
409 | //m_log.DebugFormat( | ||
410 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
411 | |||
412 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
413 | { | ||
414 | assetUuids[uuid] = (sbyte)AssetType.Texture; | ||
415 | } | ||
416 | } | 482 | } |
417 | } | 483 | } |
418 | 484 | ||
@@ -425,25 +491,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
425 | /// <param name="assetUuids"></param> | 491 | /// <param name="assetUuids"></param> |
426 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) | 492 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) |
427 | { | 493 | { |
428 | AssetBase objectAsset = GetAsset(sceneObjectUuid); | 494 | AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid); |
429 | 495 | ||
430 | if (null != objectAsset) | 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)) | ||
431 | { | 513 | { |
432 | string xml = Utils.BytesToString(objectAsset.Data); | 514 | foreach (SceneObjectGroup sog in coa.Objects) |
433 | 515 | GatherAssetUuids(sog, assetUuids); | |
434 | CoalescedSceneObjects coa; | 516 | } |
435 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | 517 | else |
436 | { | 518 | { |
437 | foreach (SceneObjectGroup sog in coa.Objects) | 519 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); |
438 | GatherAssetUuids(sog, assetUuids); | 520 | |
439 | } | 521 | if (null != sog) |
440 | else | 522 | GatherAssetUuids(sog, assetUuids); |
441 | { | ||
442 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | ||
443 | |||
444 | if (null != sog) | ||
445 | GatherAssetUuids(sog, assetUuids); | ||
446 | } | ||
447 | } | 523 | } |
448 | } | 524 | } |
449 | 525 | ||
@@ -454,12 +530,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | /// <param name="assetUuids"></param> | 530 | /// <param name="assetUuids"></param> |
455 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) | 531 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) |
456 | { | 532 | { |
457 | AssetBase assetBase = GetAsset(gestureUuid); | 533 | AssetBase gestureAsset = GetAsset(gestureUuid); |
458 | if (null == assetBase) | 534 | if (null == gestureAsset) |
459 | return; | 535 | return; |
460 | 536 | ||
461 | using (MemoryStream ms = new MemoryStream(assetBase.Data)) | 537 | GetGestureAssetUuids(gestureAsset, assetUuids); |
462 | using (StreamReader sr = new StreamReader(ms)) | 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)) | ||
463 | { | 549 | { |
464 | sr.ReadLine(); // Unknown (Version?) | 550 | sr.ReadLine(); // Unknown (Version?) |
465 | sr.ReadLine(); // Unknown | 551 | sr.ReadLine(); // Unknown |
@@ -500,7 +586,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
500 | if (null == assetBase) | 586 | if (null == assetBase) |
501 | return; | 587 | return; |
502 | 588 | ||
503 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data); | 589 | GetMaterialAssetUuids(assetBase, assetUuids); |
590 | } | ||
591 | |||
592 | /// <summary> | ||
593 | /// Get the asset uuid's referenced in a material. | ||
594 | /// </summary> | ||
595 | private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids) | ||
596 | { | ||
597 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); | ||
504 | 598 | ||
505 | UUID normMap = mat["NormMap"].AsUUID(); | 599 | UUID normMap = mat["NormMap"].AsUUID(); |
506 | if (normMap != UUID.Zero) | 600 | if (normMap != UUID.Zero) |