Пример #1
0
        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));
        }