示例#1
0
        /// <summary>
        ///     针对.patch_list和.manifest,对所有更新过的补丁资源,进行检验
        /// </summary>
        /// <returns></returns>
        private bool VerifyPatchResources()
        {
            PatchListFile patchList       = null;
            List <string> patchListRemove = null; // 将被从patchList移除的字符串缓存

            if (Directory.Exists(_localUpdatePath) &&
                File.Exists(PatchListFilePath) && File.Exists(ManifestFilePath))
            {
                patchList       = new PatchListFile(PatchListFilePath);
                patchListRemove = new List <string>();
                var manifestData = new ManifestFile(ManifestFilePath);

                //                var time = Time.time;
                foreach (var relativePath in patchList.Datas)
                {
                    var fileName = Path.GetFileName(relativePath);
                    if (fileName.StartsWith(".")) // 忽略.manifest, .resource_version
                    {
                        continue;
                    }

                    // 校验
                    var fullPath = Path.Combine(this._localUpdatePath, relativePath);
                    if (!manifestData.Datas.ContainsKey(relativePath) && File.Exists(fullPath))
                    {
                        // 多出来的文件,清理掉
                        AppendLog("Warn useless `{0}` in .manifest file", relativePath);
                        File.Delete(fullPath);
                        patchListRemove.Add(relativePath);
                        // patch_list存在,但不存在具体文件,证明之前资源包被删掉了
                    }
                    else
                    {
                        if (!File.Exists(fullPath))
                        {
                            OnError(this, "Error not found file `{0}`", fullPath);
                            goto Exit0;
                        }
                        var manifestMd5 = manifestData.Datas[relativePath].MD5.ToLower();
                        var realMd5     = Md5Helper.Md5File(fullPath).ToLower();

                        if (manifestMd5 != realMd5)
                        {
                            OnError(this, "Error when md5 verify, need: {0}, but: {1}", realMd5, manifestMd5);
                            goto Exit0;
                        }
                        //                        if (Time.time - time > 0.1f) // 帧速过慢了,回停一下
                        //                        {
                        //                            time = Time.time;
                        //                            yield return null;
                        //                        }
                    }
                }

                // 搜寻patch_resources目录,确保里面的文件都在.patch_List里!
                var patchResourcesDirPath = _localUpdatePath;
                foreach (var filePath in Directory.GetFiles(patchResourcesDirPath, "*", SearchOption.AllDirectories))
                {
                    var fileName = Path.GetFileName(filePath);
                    if (fileName.StartsWith("."))
                    {
                        continue;                           // 忽略隐藏文件
                    }
                    var cleanPath =
                        filePath.Substring(patchResourcesDirPath.Length + 1,
                                           filePath.Length - patchResourcesDirPath.Length - 1).Replace("\\", "/"); // + - 1为了砍掉/
                    if (!patchList.Datas.Contains(cleanPath))
                    {
                        OnError(this, "patch_resources file: {0} not in .patch_list", filePath);
                        goto Exit0;
                    }
                }
            }
            // else 不用处理了, CheckAppValid会做检查

            CleanPatchList(patchList, patchListRemove);
            //            verifyResult[0] = true;
            //            yield break;
            return(true);

Exit0:
            // 验证失败,将清理下载资源。重新走更新流程,会重新下载资源
            ClearAllPatchResources();
            CleanPatchList(patchList, patchListRemove);
            //            verifyResult[0] = false;
            return(false);
        }
        protected internal override void Start()
        {
            var zipPath = _downloader.GetSavePath();

            // 获取压缩文件数量
            using (var zipFile = new ZipFile(zipPath))
            {
                TotalDecompressSize   = zipFile.Count;
                DecompressCurrentSize = 0;
            }
            using (var s = new ZipInputStream(File.OpenRead(zipPath)))
            {
                // 进度条重新来过
                //_progressBarCount = 0;
                //_progressBarCountLastSecond = 0;  // 重来
                //_progressBarTotalCount = (int)zipJson.Size; // 重新计算进度条

                ZipEntry theEntry;
                //var timeCount = Time.realtimeSinceStartup;

                try
                {
                    while ((theEntry = s.GetNextEntry()) != null)
                    {
                        if (theEntry.IsDirectory)
                        {
                            continue;
                        }

                        var    cleanPath    = theEntry.Name.Replace("\\", "/");
                        string directorName = Path.Combine(LocalUpdatePath, Path.GetDirectoryName(cleanPath));

                        var fileName = Path.GetFileName(cleanPath);
                        // 其它解压
                        string fullFileName = Path.Combine(directorName, fileName);
                        _decompressedList.Add(cleanPath);

                        if (!Directory.Exists(directorName))
                        {
                            Directory.CreateDirectory(directorName);
                        }
                        if (!String.IsNullOrEmpty(fullFileName))
                        {
                            using (FileStream streamWriter = File.Create(fullFileName))
                            {
                                byte[] data = new byte[s.Length];
                                s.Read(data, 0, data.Length);
                                streamWriter.Write(data, 0, data.Length);

                                DecompressCurrentSize++;
                                AppendLog("解压文件: {0}, 解压的大小: {1}KB", cleanPath,
                                          data.Length / 1024f);
                                // 忽略下面的resharper dispose 提示。。。,因为协程里没这问题
                                //decompressLogs.Add(cleanName); // 记录解压的文件,用于断电续传
                            }
                        }
                    }

                    if (OnDecompressedEvent != null)
                    {
                        OnDecompressedEvent(this, _decompressedList);
                    }

                    var patchList = new PatchListFile(PatchListPath);

                    if (File.Exists(DeletedFilePath))
                    {
                        var deleteFile = new DeletedListFile(DeletedFilePath);

                        foreach (var path in deleteFile.Datas)
                        {
                            var fullPath = Path.Combine(LocalUpdatePath, path);
                            if (File.Exists(fullPath))
                            {
                                File.Delete(fullPath);
                            }
                            else
                            {
                                AppendLog("Not exist file in .deleted file list: {0}", deleteFile);
                            }
                            // remove from patchList
                            patchList.Datas.Remove(path);
                        }

                        // delete the .deleted file
                        File.Delete(DeletedFilePath);
                    }

                    // 解压的文件进行验证
                    // 进行解压的文件校验
                    var manifestTable = new ManifestFile(ManifestPath);
                    foreach (var checkPath in _decompressedList)
                    {
                        // .manifest, .delete文件不进行验证
                        if (checkPath == ManifestFileName)
                        {
                            continue;
                        }
                        if (checkPath == DeletedFileName)
                        {
                            continue;
                        }

                        var checkFullPath = Path.Combine(LocalUpdatePath, checkPath);
                        ManifestFile.Manifest checkMani;
                        if (!manifestTable.Datas.TryGetValue(checkPath, out checkMani))
                        {
                            throw new Exception(string.Format("Error when check file: {0}, no manifest data", checkPath));
                        }

                        if (!File.Exists(checkFullPath))
                        {
                            throw new Exception(string.Format("Error when check file: {0} not exist", checkFullPath));
                        }

                        var expectMd5 = checkMani;
                        var fileMd5   = Md5Helper.Md5File(checkFullPath);
                        if (expectMd5.MD5.ToLower() != fileMd5.ToLower())
                        {
                            throw new Exception(string.Format("Error verify on {0}, expect:{1}, but:{2}", checkFullPath,
                                                              expectMd5.MD5, fileMd5));
                        }
                    }

                    // 读取、创建.patch_list
                    foreach (var file in _decompressedList)
                    {
                        patchList.Add(file);
                    }
                    patchList.Save();

                    LocalVersionFile.Write(LocalUpdatePath, ResourceVersionFileName, _downloader.RemoteVersion);
                }
                catch (Exception e)
                {
                    OnError(this, e.Message);
                }
            }

            if (IsDeleteZip)
            {
                // 解压完成,对压缩包进行删除
                if (File.Exists(zipPath))
                {
                    File.Delete(zipPath);
                }
            }

            Finish();
        }