private static Index DuplicateInstance(Index srcIndex, bool stripInstance) { //Debug.Log("DuplicateInstance - Started"); Index dstIndex = null; if (srcIndex != null) { dstIndex = new Index(); dstIndex.m_filename = srcIndex.m_filename; if (!stripInstance) { dstIndex.m_buildTag = srcIndex.m_buildTag; } dstIndex.m_assetBundles = new List <AssetBundle>(); dstIndex.m_assetBundles.Clear(); foreach (Index.AssetBundle srcAssetBundle in srcIndex.m_assetBundles) { Index.AssetBundle dstAssetBundle = new Index.AssetBundle(); dstAssetBundle.m_filename = srcAssetBundle.m_filename; dstAssetBundle.m_type = srcAssetBundle.m_type; dstAssetBundle.m_isCompressed = srcAssetBundle.m_isCompressed; if (!stripInstance) { dstAssetBundle.m_size = srcAssetBundle.m_size; dstAssetBundle.m_contentHash = srcAssetBundle.m_contentHash; if (srcAssetBundle.m_urls != null) { dstAssetBundle.m_urls = new string[srcAssetBundle.m_urls.Length]; Array.Copy(srcAssetBundle.m_urls, dstAssetBundle.m_urls, srcAssetBundle.m_urls.Length); } else { dstAssetBundle.m_urls = null; } } dstAssetBundle.m_assets = new List <Index.AssetBundle.Asset>(); dstAssetBundle.m_assets.Clear(); foreach (Index.AssetBundle.Asset srcAsset in srcAssetBundle.m_assets) { Index.AssetBundle.Asset dstAsset = new Index.AssetBundle.Asset(); dstAsset.m_filename = srcAsset.m_filename; dstAsset.m_guid = srcAsset.m_guid; if (!stripInstance) { dstAsset.m_hash = srcAsset.m_hash; } dstAssetBundle.m_assets.Add(dstAsset); } dstIndex.m_assetBundles.Add(dstAssetBundle); } } //Debug.Log("DuplicateInstance - Finished"); return(dstIndex); }
// TODO: comment it: computes hash of the asset bundle based on the specified assets public static string ComputeAssetBundleHashDependingOnProvidedDistribution(Index index, Index.AssetBundle assetBundle) { Index.AssetBundle userAssetBundle = assetBundle; Index.AssetBundle realAssetBundle = null; foreach (Index.AssetBundle ab in index.m_assetBundles) { if (ab.m_filename.Equals(userAssetBundle.m_filename)) { realAssetBundle = ab; break; } } Assertion.Check(realAssetBundle != null); // SANITY CHECK // create a list contained user-defined assets (they could become just references) List <string> references = new List <string>(); foreach (Index.AssetBundle.Asset asset in userAssetBundle.m_assets) { references.Add(asset.m_filename); } // now compute hash for the asset bundle string ret = ""; foreach (Index.AssetBundle.Asset asset in realAssetBundle.m_assets) { string hash = File.Exists(asset.m_filename) ? ETUtils.CreateHashForAsset(asset.m_filename) : null; // hash of the content ret = ETUtils.HashXorHash(ret, hash); } foreach (string assetFilepath in references) { string hash = ETUtils.CreateHashForString(assetFilepath); // hash of explicit asset name ret = ETUtils.HashXorHash(ret, hash); } return(ret); // return null to compute hashes with base (incorrent) algorithm }
// TODO: comment it: gets distribution (which assets in which bundles) in reality public static Index ReorganizeDistribution(Index index) { Dictionary <string, Index.AssetBundle> userAssetsToBundles = GetUserDistribution(index); Dictionary <string, Index.AssetBundle> realAssetsToBundles = GetRealDistribution(userAssetsToBundles); Dictionary <string, List <string> > dist = new Dictionary <string, List <string> >(); foreach (KeyValuePair <string, Index.AssetBundle> kvp in realAssetsToBundles) { if (!dist.ContainsKey(kvp.Value.m_filename)) { dist.Add(kvp.Value.m_filename, new List <string>()); } dist[kvp.Value.m_filename].Add(kvp.Key); } index = Index.DuplicateInstance(index); HashSet <Index.AssetBundle> checkedAssetBundles = new HashSet <Index.AssetBundle>(); HashSet <Index.AssetBundle.Asset> checkedAssets = new HashSet <Index.AssetBundle.Asset>(); foreach (KeyValuePair <string, List <string> > kvp in dist) { Index.AssetBundle assetBundle = null; foreach (Index.AssetBundle ab in index.m_assetBundles) { if (ab.m_filename.Equals(kvp.Key)) { assetBundle = ab; break; } } Assertion.Check(assetBundle != null); if (assetBundle != null) { foreach (string val in kvp.Value) { Index.AssetBundle.Asset asset = null; foreach (Index.AssetBundle.Asset a in assetBundle.m_assets) { if (a.m_filename.Equals(val)) { asset = a; break; } } if (asset == null) { asset = new Index.AssetBundle.Asset(); asset.m_filename = val; asset.m_guid = AssetDatabase.AssetPathToGUID(asset.m_filename); assetBundle.m_assets.Add(asset); } asset.m_hash = File.Exists(asset.m_filename) ? ETUtils.CreateHashForAsset(asset.m_filename) : null; checkedAssets.Add(asset); } checkedAssetBundles.Add(assetBundle); } } foreach (Index.AssetBundle assetBundle in index.m_assetBundles) { if (checkedAssetBundles.Contains(assetBundle)) { for (int idx = assetBundle.m_assets.Count - 1; idx >= 0; --idx) { if (!checkedAssets.Contains(assetBundle.m_assets[idx])) { assetBundle.m_assets.RemoveAt(idx); } } } else { assetBundle.m_assets.Clear(); } } return(index); }
// TODO: comment it: computes hash of the asset bundle based on actually included assets only (not references!) public static string ComputeAssetBundleHashDependingOnRealDistribution(Index index, Index.AssetBundle assetBundle) { // reorganize distribution, so hash would be computed as they should, // i.e. based on real assets (and not their references) in the bundle Index userIndex = index; Index realIndex = ReorganizeDistribution(userIndex); return(ComputeAssetBundleHashDependingOnProvidedDistribution(realIndex, assetBundle)); }