From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001 From: onefang Date: Sun, 19 May 2019 21:24:15 +1000 Subject: Dump OpenSim 0.9.0.1 into it's own branch. --- OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 231 ++++++++++++++++-------- 1 file changed, 158 insertions(+), 73 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UuidGatherer.cs') diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 2070ce5..80d3f62 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -65,7 +65,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// The gathered uuids. public IDictionary GatheredUuids { get; private set; } - + public HashSet FailedUUIDs { get; private set; } + public HashSet UncertainAssetsUUIDs { get; private set; } + public int possibleNotAssetCount { get; set; } + public int ErrorCount { get; private set; } /// /// Gets the next UUID to inspect. /// @@ -92,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// Asset service. /// - public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary()) {} + public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary(), + new HashSet (),new HashSet ()) {} + public UuidGatherer(IAssetService assetService, IDictionary collector) : this(assetService, collector, + new HashSet (), new HashSet ()) {} /// /// Initializes a new instance of the class. @@ -101,16 +107,20 @@ namespace OpenSim.Region.Framework.Scenes /// Asset service. /// /// - /// Gathered UUIDs will be collected in this dictinaory. + /// Gathered UUIDs will be collected in this dictionary. /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected. /// - public UuidGatherer(IAssetService assetService, IDictionary collector) + public UuidGatherer(IAssetService assetService, IDictionary collector, HashSet failedIDs, HashSet uncertainAssetsUUIDs) { m_assetService = assetService; GatheredUuids = collector; // FIXME: Not efficient for searching, can improve. m_assetUuidsToInspect = new Queue(); + FailedUUIDs = failedIDs; + UncertainAssetsUUIDs = uncertainAssetsUUIDs; + ErrorCount = 0; + possibleNotAssetCount = 0; } /// @@ -120,16 +130,28 @@ namespace OpenSim.Region.Framework.Scenes /// UUID. public bool AddForInspection(UUID uuid) { + if(uuid == UUID.Zero) + return false; + + if(FailedUUIDs.Contains(uuid)) + { + if(UncertainAssetsUUIDs.Contains(uuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return false; + } + if(GatheredUuids.ContainsKey(uuid)) + return false; if (m_assetUuidsToInspect.Contains(uuid)) return false; // m_log.DebugFormat("[UUID GATHERER]: Adding asset {0} for inspection", uuid); m_assetUuidsToInspect.Enqueue(uuid); - return true; } - + /// /// Gather all the asset uuids associated with a given object. /// @@ -142,7 +164,9 @@ namespace OpenSim.Region.Framework.Scenes public void AddForInspection(SceneObjectGroup sceneObject) { // m_log.DebugFormat( - // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); + // "[UUID GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); + if(sceneObject.IsDeleted) + return; SceneObjectPart[] parts = sceneObject.Parts; for (int i = 0; i < parts.Length; i++) @@ -150,7 +174,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = parts[i]; // m_log.DebugFormat( - // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); + // "[UUID GATHERER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { @@ -179,8 +203,10 @@ namespace OpenSim.Region.Framework.Scenes if (part.Shape.ProjectionTextureUUID != UUID.Zero) GatheredUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; - if (part.CollisionSound != UUID.Zero) - GatheredUuids[part.CollisionSound] = (sbyte)AssetType.Sound; + UUID collisionSound = part.CollisionSound; + if ( collisionSound != UUID.Zero && + collisionSound != part.invalidCollisionSoundUUID) + GatheredUuids[collisionSound] = (sbyte)AssetType.Sound; if (part.ParticleSystem.Length > 0) { @@ -193,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception) { m_log.WarnFormat( - "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.", + "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.", part.Name, part.UUID, sceneObject.Name, sceneObject.UUID); } } @@ -204,29 +230,24 @@ namespace OpenSim.Region.Framework.Scenes foreach (TaskInventoryItem tii in taskDictionary.Values) { // m_log.DebugFormat( - // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", + // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", // tii.Name, tii.Type, part.Name, part.UUID); - - if (!GatheredUuids.ContainsKey(tii.AssetID)) - AddForInspection(tii.AssetID, (sbyte)tii.Type); + AddForInspection(tii.AssetID, (sbyte)tii.Type); } // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and - // inventory transfer. There needs to be a way for a module to register a method without assuming a + // inventory transfer. There needs to be a way for a module to register a method without assuming a // Scene.EventManager is present. // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs - RecordMaterialsUuids(part); + RecordMaterialsUuids(part); } catch (Exception e) { m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); - m_log.DebugFormat( - "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", - part.Shape.TextureEntry.Length); } } } @@ -277,58 +298,115 @@ namespace OpenSim.Region.Framework.Scenes /// The uuid of the asset for which to gather referenced assets private void GetAssetUuids(UUID assetUuid) { + if(assetUuid == UUID.Zero) + return; + + if(FailedUUIDs.Contains(assetUuid)) + { + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } + // avoid infinite loops if (GatheredUuids.ContainsKey(assetUuid)) return; + AssetBase assetBase; try - { - AssetBase assetBase = GetAsset(assetUuid); + { + assetBase = GetAsset(assetUuid); + } + catch (Exception e) + { + m_log.ErrorFormat("[UUID GATHERER]: Failed to get asset {0} : {1}", assetUuid, e.Message); + ErrorCount++; + FailedUUIDs.Add(assetUuid); + return; + } - if (null != assetBase) - { - sbyte assetType = assetBase.Type; - GatheredUuids[assetUuid] = assetType; + if(assetBase == null) + { +// m_log.ErrorFormat("[UUID GATHERER]: asset {0} not found", assetUuid); + FailedUUIDs.Add(assetUuid); + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } - if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) - { - RecordWearableAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Gesture == assetType) - { - RecordGestureAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Notecard == assetType) - { - RecordTextEmbeddedAssetUuids(assetBase); - } - else if ((sbyte)AssetType.LSLText == assetType) - { - RecordTextEmbeddedAssetUuids(assetBase); - } - else if ((sbyte)OpenSimAssetType.Material == assetType) - { - RecordMaterialAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Object == assetType) - { - RecordSceneObjectAssetUuids(assetBase); - } + if(UncertainAssetsUUIDs.Contains(assetUuid)) + UncertainAssetsUUIDs.Remove(assetUuid); + + sbyte assetType = assetBase.Type; + + if(assetBase.Data == null || assetBase.Data.Length == 0) + { +// m_log.ErrorFormat("[UUID GATHERER]: asset {0}, type {1} has no data", assetUuid, assetType); + ErrorCount++; + FailedUUIDs.Add(assetUuid); + return; + } + + GatheredUuids[assetUuid] = assetType; + try + { + if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) + { + RecordWearableAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Gesture == assetType) + { + RecordGestureAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Notecard == assetType) + { + RecordTextEmbeddedAssetUuids(assetBase); + } + else if ((sbyte)AssetType.LSLText == assetType) + { + RecordTextEmbeddedAssetUuids(assetBase); + } + else if ((sbyte)OpenSimAssetType.Material == assetType) + { + RecordMaterialAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Object == assetType) + { + RecordSceneObjectAssetUuids(assetBase); } } - catch (Exception) + catch (Exception e) { - m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); - throw; + m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset with id {0} type {1}: {2}", assetUuid, assetType, e.Message); + GatheredUuids.Remove(assetUuid); + ErrorCount++; + FailedUUIDs.Add(assetUuid); } - } + } private void AddForInspection(UUID assetUuid, sbyte assetType) { + if(assetUuid == UUID.Zero) + return; + // Here, we want to collect uuids which require further asset fetches but mark the others as gathered + if(FailedUUIDs.Contains(assetUuid)) + { + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } + if(GatheredUuids.ContainsKey(assetUuid)) + return; try - { - if ((sbyte)AssetType.Bodypart == assetType + { + if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType || (sbyte)AssetType.Gesture == assetType || (sbyte)AssetType.Notecard == assetType @@ -346,7 +424,7 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception) { m_log.ErrorFormat( - "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}", + "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}", assetUuid, assetType); throw; } @@ -457,8 +535,11 @@ namespace OpenSim.Region.Framework.Scenes foreach (Match uuidMatch in uuidMatches) { UUID uuid = new UUID(uuidMatch.Value); + if(uuid == UUID.Zero) + continue; // m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid); - + if(!UncertainAssetsUUIDs.Contains(uuid)) + UncertainAssetsUUIDs.Add(uuid); AddForInspection(uuid); } } @@ -490,23 +571,18 @@ namespace OpenSim.Region.Framework.Scenes { string xml = Utils.BytesToString(sceneObjectAsset.Data); - if (String.IsNullOrEmpty(xml)) - m_log.ErrorFormat("[UUIDGatherer]: Asset {0} - {1} has a zero length XML blob!", sceneObjectAsset.Name, sceneObjectAsset.ID); + CoalescedSceneObjects coa; + if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) + { + foreach (SceneObjectGroup sog in coa.Objects) + AddForInspection(sog); + } else { - CoalescedSceneObjects coa; - if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) - { - foreach (SceneObjectGroup sog in coa.Objects) - AddForInspection(sog); - } - else - { - SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); + SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); - if (null != sog) - AddForInspection(sog); - } + if (null != sog) + AddForInspection(sog); } } @@ -554,7 +630,16 @@ namespace OpenSim.Region.Framework.Scenes /// private void RecordMaterialAssetUuids(AssetBase materialAsset) { - OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); + OSDMap mat; + try + { + mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); + } + catch (Exception e) + { + m_log.WarnFormat("[Materials]: cannot decode material asset {0}: {1}", materialAsset.ID, e.Message); + return; + } UUID normMap = mat["NormMap"].AsUUID(); if (normMap != UUID.Zero) -- cgit v1.1