aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/UuidGatherer.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs265
1 files changed, 142 insertions, 123 deletions
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 2450cdb..2c5353f 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -648,6 +648,15 @@ namespace OpenSim.Region.Framework.Scenes
648 } 648 }
649 } 649 }
650 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>
651 public class IteratingUuidGatherer 660 public class IteratingUuidGatherer
652 { 661 {
653 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 662 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -678,21 +687,31 @@ namespace OpenSim.Region.Framework.Scenes
678 687
679 protected Queue<UUID> m_assetUuidsToInspect; 688 protected Queue<UUID> m_assetUuidsToInspect;
680 689
681 public IteratingUuidGatherer(IAssetService assetService) 690 /// <summary>
691 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
692 /// </summary>
693 /// <param name="assetService">
694 /// Asset service.
695 /// </param>
696 /// <param name="collector">
697 /// 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.
699 /// </param>
700 public IteratingUuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
682 { 701 {
683 m_assetService = assetService; 702 m_assetService = assetService;
684 m_gatheredAssetUuids = new Dictionary<UUID, sbyte>(); 703 m_gatheredAssetUuids = collector;
685 704
686 // FIXME: Not efficient for searching, can improve. 705 // FIXME: Not efficient for searching, can improve.
687 m_assetUuidsToInspect = new Queue<UUID>(); 706 m_assetUuidsToInspect = new Queue<UUID>();
688 } 707 }
689 708
690 public IDictionary<UUID, sbyte> GetGatheredUuids() 709 /// <summary>
691 { 710 /// Adds the asset uuid for inspection during the gathering process.
692 return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids); 711 /// </summary>
693 } 712 /// <returns><c>true</c>, if for inspection was added, <c>false</c> otherwise.</returns>
694 713 /// <param name="uuid">UUID.</param>
695 public bool AddAssetUuidToInspect(UUID uuid) 714 public bool AddForInspection(UUID uuid)
696 { 715 {
697 if (m_assetUuidsToInspect.Contains(uuid)) 716 if (m_assetUuidsToInspect.Contains(uuid))
698 return false; 717 return false;
@@ -701,6 +720,107 @@ namespace OpenSim.Region.Framework.Scenes
701 720
702 return true; 721 return true;
703 } 722 }
723
724 /// <summary>
725 /// Gather all the asset uuids associated with a given object.
726 /// </summary>
727 /// <remarks>
728 /// This includes both those directly associated with
729 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
730 /// within this object).
731 /// </remarks>
732 /// <param name="sceneObject">The scene object for which to gather assets</param>
733 public void AddForInspection(SceneObjectGroup sceneObject)
734 {
735 // m_log.DebugFormat(
736 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
737
738 SceneObjectPart[] parts = sceneObject.Parts;
739 for (int i = 0; i < parts.Length; i++)
740 {
741 SceneObjectPart part = parts[i];
742
743 // m_log.DebugFormat(
744 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
745
746 try
747 {
748 Primitive.TextureEntry textureEntry = part.Shape.Textures;
749 if (textureEntry != null)
750 {
751 // Get the prim's default texture. This will be used for faces which don't have their own texture
752 if (textureEntry.DefaultTexture != null)
753 RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
754
755 if (textureEntry.FaceTextures != null)
756 {
757 // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
758 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
759 {
760 if (texture != null)
761 RecordTextureEntryAssetUuids(texture);
762 }
763 }
764 }
765
766 // If the prim is a sculpt then preserve this information too
767 if (part.Shape.SculptTexture != UUID.Zero)
768 m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
769
770 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
771 m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
772
773 if (part.CollisionSound != UUID.Zero)
774 m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
775
776 if (part.ParticleSystem.Length > 0)
777 {
778 try
779 {
780 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
781 if (ps.Texture != UUID.Zero)
782 m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
783 }
784 catch (Exception)
785 {
786 m_log.WarnFormat(
787 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
788 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
789 }
790 }
791
792 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
793
794 // Now analyze this prim's inventory items to preserve all the uuids that they reference
795 foreach (TaskInventoryItem tii in taskDictionary.Values)
796 {
797 // m_log.DebugFormat(
798 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
799 // tii.Name, tii.Type, part.Name, part.UUID);
800
801 if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
802 AddForInspection(tii.AssetID, (sbyte)tii.Type);
803 }
804
805 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
806 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
807 // inventory transfer. There needs to be a way for a module to register a method without assuming a
808 // Scene.EventManager is present.
809 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
810
811
812 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
813 RecordMaterialsUuids(part);
814 }
815 catch (Exception e)
816 {
817 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
818 m_log.DebugFormat(
819 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
820 part.Shape.TextureEntry.Length);
821 }
822 }
823 }
704 824
705 /// <summary> 825 /// <summary>
706 /// Gathers the next set of assets returned by the next uuid to get from the asset service. 826 /// Gathers the next set of assets returned by the next uuid to get from the asset service.
@@ -790,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
790 } 910 }
791 } 911 }
792 912
793 private void RecordAssetUuids(UUID assetUuid, sbyte assetType) 913 private void AddForInspection(UUID assetUuid, sbyte assetType)
794 { 914 {
795 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered 915 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
796 try 916 try
@@ -799,27 +919,27 @@ namespace OpenSim.Region.Framework.Scenes
799 919
800 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 920 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
801 { 921 {
802 AddAssetUuidToInspect(assetUuid); 922 AddForInspection(assetUuid);
803 } 923 }
804 else if ((sbyte)AssetType.Gesture == assetType) 924 else if ((sbyte)AssetType.Gesture == assetType)
805 { 925 {
806 AddAssetUuidToInspect(assetUuid); 926 AddForInspection(assetUuid);
807 } 927 }
808 else if ((sbyte)AssetType.Notecard == assetType) 928 else if ((sbyte)AssetType.Notecard == assetType)
809 { 929 {
810 AddAssetUuidToInspect(assetUuid); 930 AddForInspection(assetUuid);
811 } 931 }
812 else if ((sbyte)AssetType.LSLText == assetType) 932 else if ((sbyte)AssetType.LSLText == assetType)
813 { 933 {
814 AddAssetUuidToInspect(assetUuid); 934 AddForInspection(assetUuid);
815 } 935 }
816 else if ((sbyte)OpenSimAssetType.Material == assetType) 936 else if ((sbyte)OpenSimAssetType.Material == assetType)
817 { 937 {
818 AddAssetUuidToInspect(assetUuid); 938 AddForInspection(assetUuid);
819 } 939 }
820 else if ((sbyte)AssetType.Object == assetType) 940 else if ((sbyte)AssetType.Object == assetType)
821 { 941 {
822 AddAssetUuidToInspect(assetUuid); 942 AddForInspection(assetUuid);
823 } 943 }
824 } 944 }
825 catch (Exception) 945 catch (Exception)
@@ -832,107 +952,6 @@ namespace OpenSim.Region.Framework.Scenes
832 } 952 }
833 953
834 /// <summary> 954 /// <summary>
835 /// Gather all the asset uuids associated with a given object.
836 /// </summary>
837 /// <remarks>
838 /// This includes both those directly associated with
839 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
840 /// within this object).
841 /// </remarks>
842 /// <param name="sceneObject">The scene object for which to gather assets</param>
843 public void RecordAssetUuids(SceneObjectGroup sceneObject)
844 {
845 // m_log.DebugFormat(
846 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
847
848 SceneObjectPart[] parts = sceneObject.Parts;
849 for (int i = 0; i < parts.Length; i++)
850 {
851 SceneObjectPart part = parts[i];
852
853 // m_log.DebugFormat(
854 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
855
856 try
857 {
858 Primitive.TextureEntry textureEntry = part.Shape.Textures;
859 if (textureEntry != null)
860 {
861 // Get the prim's default texture. This will be used for faces which don't have their own texture
862 if (textureEntry.DefaultTexture != null)
863 RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
864
865 if (textureEntry.FaceTextures != null)
866 {
867 // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
868 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
869 {
870 if (texture != null)
871 RecordTextureEntryAssetUuids(texture);
872 }
873 }
874 }
875
876 // If the prim is a sculpt then preserve this information too
877 if (part.Shape.SculptTexture != UUID.Zero)
878 m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
879
880 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
881 m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
882
883 if (part.CollisionSound != UUID.Zero)
884 m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
885
886 if (part.ParticleSystem.Length > 0)
887 {
888 try
889 {
890 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
891 if (ps.Texture != UUID.Zero)
892 m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
893 }
894 catch (Exception)
895 {
896 m_log.WarnFormat(
897 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
898 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
899 }
900 }
901
902 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
903
904 // Now analyze this prim's inventory items to preserve all the uuids that they reference
905 foreach (TaskInventoryItem tii in taskDictionary.Values)
906 {
907 // m_log.DebugFormat(
908 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
909 // tii.Name, tii.Type, part.Name, part.UUID);
910
911 if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
912 RecordAssetUuids(tii.AssetID, (sbyte)tii.Type);
913 }
914
915 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
916 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
917 // inventory transfer. There needs to be a way for a module to register a method without assuming a
918 // Scene.EventManager is present.
919 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
920
921
922 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
923 RecordMaterialsUuids(part);
924 }
925 catch (Exception e)
926 {
927 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
928 m_log.DebugFormat(
929 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
930 part.Shape.TextureEntry.Length);
931 }
932 }
933 }
934
935 /// <summary>
936 /// Collect all the asset uuids found in one face of a Texture Entry. 955 /// Collect all the asset uuids found in one face of a Texture Entry.
937 /// </summary> 956 /// </summary>
938 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture) 957 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture)
@@ -940,7 +959,7 @@ namespace OpenSim.Region.Framework.Scenes
940 m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture; 959 m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
941 960
942 if (texture.MaterialID != UUID.Zero) 961 if (texture.MaterialID != UUID.Zero)
943 AddAssetUuidToInspect(texture.MaterialID); 962 AddForInspection(texture.MaterialID);
944 } 963 }
945 964
946 /// <summary> 965 /// <summary>
@@ -948,7 +967,7 @@ namespace OpenSim.Region.Framework.Scenes
948 /// stored in legacy format in part.DynAttrs 967 /// stored in legacy format in part.DynAttrs
949 /// </summary> 968 /// </summary>
950 /// <param name="part"></param> 969 /// <param name="part"></param>
951 public void RecordMaterialsUuids(SceneObjectPart part) 970 private void RecordMaterialsUuids(SceneObjectPart part)
952 { 971 {
953 // scan thru the dynAttrs map of this part for any textures used as materials 972 // scan thru the dynAttrs map of this part for any textures used as materials
954 OSD osdMaterials = null; 973 OSD osdMaterials = null;
@@ -1039,7 +1058,7 @@ namespace OpenSim.Region.Framework.Scenes
1039 UUID uuid = new UUID(uuidMatch.Value); 1058 UUID uuid = new UUID(uuidMatch.Value);
1040 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); 1059 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
1041 1060
1042 AddAssetUuidToInspect(uuid); 1061 AddForInspection(uuid);
1043 } 1062 }
1044 } 1063 }
1045 1064
@@ -1074,14 +1093,14 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) 1093 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
1075 { 1094 {
1076 foreach (SceneObjectGroup sog in coa.Objects) 1095 foreach (SceneObjectGroup sog in coa.Objects)
1077 RecordAssetUuids(sog); 1096 AddForInspection(sog);
1078 } 1097 }
1079 else 1098 else
1080 { 1099 {
1081 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); 1100 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
1082 1101
1083 if (null != sog) 1102 if (null != sog)
1084 RecordAssetUuids(sog); 1103 AddForInspection(sog);
1085 } 1104 }
1086 } 1105 }
1087 1106
@@ -1147,8 +1166,8 @@ namespace OpenSim.Region.Framework.Scenes
1147 1166
1148 protected string m_assetServerURL; 1167 protected string m_assetServerURL;
1149 1168
1150 public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL) 1169 public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector)
1151 : base(assetService) 1170 : base(assetService, collector)
1152 { 1171 {
1153 m_assetServerURL = assetServerURL; 1172 m_assetServerURL = assetServerURL;
1154 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("=")) 1173 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))