/// <summary>
        /// 异步初始化
        /// </summary>
        public IEnumerator InitializeAsync()
        {
            MotionLog.Log($"Beginning to initialize patch manager.");

            // 加载缓存
            _cache = PatchCache.LoadCache();

            // 检测沙盒被污染
            // 注意:在覆盖安装的时候,会保留沙盒目录里的文件,所以需要强制清空
            {
                // 如果是首次打开,记录APP版本号
                if (PatchHelper.CheckSandboxCacheFileExist() == false)
                {
                    _cache.CacheAppVersion = Application.version;
                    _cache.SaveCache();
                }
                else
                {
                    // 每次启动时比对APP版本号是否一致
                    if (_cache.CacheAppVersion != Application.version)
                    {
                        MotionLog.Warning($"Cache is dirty ! Cache version is {_cache.CacheAppVersion}, APP version is {Application.version}");
                        ClearCache();

                        // 重新写入最新的APP版本号
                        _cache.CacheAppVersion = Application.version;
                        _cache.SaveCache();
                    }
                }
            }

            // 加载APP内的补丁清单
            MotionLog.Log($"Load app patch manifest.");
            {
                string        filePath   = AssetPathHelper.MakeStreamingLoadPath(PatchDefine.PatchManifestFileName);
                string        url        = AssetPathHelper.ConvertToWWWPath(filePath);
                WebGetRequest downloader = new WebGetRequest(url);
                downloader.DownLoad();
                yield return(downloader);

                if (downloader.HasError())
                {
                    downloader.ReportError();
                    downloader.Dispose();
                    throw new System.Exception($"Fatal error : Failed download file : {url}");
                }

                // 解析补丁清单
                string jsonData = downloader.GetText();
                _appPatchManifest = PatchManifest.Deserialize(jsonData);
                downloader.Dispose();
            }

            // 加载沙盒内的补丁清单
            MotionLog.Log($"Load sandbox patch manifest.");
            if (PatchHelper.CheckSandboxPatchManifestFileExist())
            {
                string filePath = AssetPathHelper.MakePersistentLoadPath(PatchDefine.PatchManifestFileName);
                string jsonData = File.ReadAllText(filePath);
                _localPatchManifest = PatchManifest.Deserialize(jsonData);
            }
            else
            {
                _localPatchManifest = _appPatchManifest;
            }
        }
Esempio n. 2
0
        public override void Update()
        {
            // 如果资源文件加载完毕
            if (States == ELoaderStates.Success || States == ELoaderStates.Fail)
            {
                UpdateAllProvider();
                return;
            }

            if (States == ELoaderStates.None)
            {
                // 检测加载地址是否为空
                if (string.IsNullOrEmpty(BundleInfo.LocalPath))
                {
                    States = ELoaderStates.Fail;
                    return;
                }

                if (string.IsNullOrEmpty(BundleInfo.RemoteURL))
                {
                    States = ELoaderStates.CheckDepends;
                }
                else
                {
                    States = ELoaderStates.Download;
                }
            }

            // 1. 从服务器下载
            if (States == ELoaderStates.Download)
            {
                _downloader = new WebFileRequest(BundleInfo.RemoteURL, BundleInfo.LocalPath);
                _downloader.DownLoad();
                States = ELoaderStates.CheckDownload;
            }

            // 2. 检测服务器下载结果
            if (States == ELoaderStates.CheckDownload)
            {
                if (_downloader.IsDone() == false)
                {
                    return;
                }

                if (_downloader.HasError())
                {
                    _downloader.ReportError();
                    States = ELoaderStates.Fail;
                }
                else
                {
                    // 校验文件完整性
                    if (AssetSystem.BundleServices.CheckContentIntegrity(BundleInfo.BundleName) == false)
                    {
                        MotionLog.Error($"Check download content integrity is failed : {BundleInfo.BundleName}");
                        States = ELoaderStates.Fail;
                    }
                    else
                    {
                        States = ELoaderStates.CheckDepends;
                    }
                }

                // 释放网络资源下载器
                if (_downloader != null)
                {
                    _downloader.Dispose();
                    _downloader = null;
                }
            }

            // 3. 检测所有依赖完成状态
            if (States == ELoaderStates.CheckDepends)
            {
                foreach (var dpLoader in _depends)
                {
                    if (dpLoader.IsDone() == false)
                    {
                        return;
                    }
                }
                States = ELoaderStates.LoadFile;
            }

            // 4. 加载AssetBundle
            if (States == ELoaderStates.LoadFile)
            {
#if UNITY_EDITOR
                // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
                if (System.IO.File.Exists(BundleInfo.LocalPath) == false)
                {
                    MotionLog.Warning($"Not found assetBundle file : {BundleInfo.LocalPath}");
                    States = ELoaderStates.Fail;
                    return;
                }
#endif

                // Load assetBundle file
                if (BundleInfo.IsEncrypted)
                {
                    if (AssetSystem.DecryptServices == null)
                    {
                        throw new Exception($"{nameof(AssetBundleLoader)} need IDecryptServices : {BundleInfo.BundleName}");
                    }

                    EDecryptMethod decryptType = AssetSystem.DecryptServices.DecryptType;
                    if (decryptType == EDecryptMethod.GetDecryptOffset)
                    {
                        ulong offset = AssetSystem.DecryptServices.GetDecryptOffset(BundleInfo);
                        _cacheRequest = AssetBundle.LoadFromFileAsync(BundleInfo.LocalPath, 0, offset);
                    }
                    else if (decryptType == EDecryptMethod.GetDecryptBinary)
                    {
                        byte[] binary = AssetSystem.DecryptServices.GetDecryptBinary(BundleInfo);
                        _cacheRequest = AssetBundle.LoadFromMemoryAsync(binary);
                    }
                    else
                    {
                        throw new NotImplementedException($"{decryptType}");
                    }
                }
                else
                {
                    _cacheRequest = AssetBundle.LoadFromFileAsync(BundleInfo.LocalPath);
                }
                States = ELoaderStates.CheckFile;
            }

            // 5. 检测AssetBundle加载结果
            if (States == ELoaderStates.CheckFile)
            {
                if (_cacheRequest.isDone == false)
                {
                    return;
                }
                CacheBundle = _cacheRequest.assetBundle;

                // Check error
                if (CacheBundle == null)
                {
                    MotionLog.Warning($"Failed to load assetBundle file : {BundleInfo.BundleName}");
                    States = ELoaderStates.Fail;
                }
                else
                {
                    States = ELoaderStates.Success;
                }
            }
        }