Beispiel #1
0
    //第二阶段更新,下载更新包
    public static IEnumerable UpdateCoroutinePhase2()
    {
        UpdateRetCode code = UpdateRetCode.success;

        if (EntryPoint.Instance.SkipUpdate)             //配置跳过更新
        {
            yield return(code);
        }

        if (Patcher.Instance.IsWritingPackFileExist())
        {
            code = UpdateRetCode.pack_err;
            UpdateInfoUtil.SetCanPlay(false);

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_LastWritePackErr);

            Patcher.Instance.LogString("Last IsWritingPackFileExist!");
            yield return(code);
        }

        //初始化pck环境
        code = Patcher.Instance.InitPackages();
        if (code != UpdateRetCode.success)
        {
            Patcher.Instance.ReleasePackages();     //释放pck环境

            UpdateInfoUtil.SetCanPlay(false);
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_OpenPackFileErr);

            Patcher.Instance.LogString("InitPackages Failed!");
            yield return(code);
        }

        //清除写包标志,如果成功打开包
        Patcher.Instance.WritePacking(false);

        yield return(null);

        //
        ELEMENT_VER verBegin  = Patcher.Instance.m_CurrentVersion;
        ELEMENT_VER verLatest = Patcher.Instance.m_VersionMan.VerLastest;

        //检查磁盘空间
        long packSizeOverAll = Patcher.Instance.m_VersionMan.CalcSize(verBegin, verLatest);

        code = Patcher.Instance.CheckDiskFreeSpace(packSizeOverAll + 100 * 1024 * 1024);
        if (code != UpdateRetCode.success)
        {
            UpdateInfoUtil.SetCanPlay(false);
            yield return(new WaitForSeconds(1.0f));

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_DiskSpaceFullErr);

            Patcher.Instance.LogString("CheckDiskFreeSpace Failed!");
            yield return(code);
        }

        while (true)
        {
            if (Patcher.Instance.m_CurrentVersion == verLatest ||                            //更新完成
                Patcher.Instance.m_CurrentVersion > verLatest)
            {
                Patcher.Instance.ReleasePackages();

                code = UpdateRetCode.success;

                UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, 1.0f);
                UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 1.0f);

                UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_Success);
                yield return(code);                                                                 //退出coroutine
            }
            else if (Patcher.Instance.m_CurrentVersion < Patcher.Instance.m_VersionMan.VerSeperate) //本地版本过旧
            {
                Patcher.Instance.ReleasePackages();

                code = UpdateRetCode.patcher_version_too_new;

                UpdateInfoUtil.SetCanPlay(false);
                yield return(new WaitForSeconds(1.0f));

                UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_LocalVersionTooOldErr);
                yield return(code);                //退出coroutine
            }

            //找到版本pair
            code = Patcher.Instance.FindVersionPair();
            if (code != UpdateRetCode.success)
            {
                Patcher.Instance.ReleasePackages();

                UpdateInfoUtil.SetCanPlay(false);
                yield return(new WaitForSeconds(1.0f));

                UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_ServerMaintananceErr);

                Patcher.Instance.LogString("FindVersionPair Failed!");
                yield return(code);               //退出coroutine
            }
            else
            {
                //当前version_pair
                Patcher.Instance.LogString(HobaText.Format("Will update from {0} to {1}", Patcher.Instance.m_PackFileVer.VerFrom.ToString(), Patcher.Instance.m_PackFileVer.VerTo.ToString()));
            }

            yield return(null);

            //更新
            foreach (var item in Patcher.Instance.UpdateAutoCoroutine(verBegin, verLatest))
            {
                if (item is UpdateRetCode)
                {
                    code = (UpdateRetCode)item;
                    break;
                }

                yield return(item);
            }
            if (code != UpdateRetCode.success)
            {
                break;
            }
        }

        switch (code)
        {
        case UpdateRetCode.success:
        {
            UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, 1.0f);
            UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 1.0f);
            yield return(null);
        }
        break;

        case UpdateRetCode.md5_not_match:
        {
            Patcher.Instance.LogString(HobaText.Format("AutoUpdate Failed! {0}", code));
            UpdateInfoUtil.SetCanPlay(false);
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_NetUnstable);
            yield return(null);
        }
        break;

        case UpdateRetCode.connect_fail:
        {
            Patcher.Instance.LogString(HobaText.Format("AutoUpdate Failed! {0}", code));
            UpdateInfoUtil.SetCanPlay(false);
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_NetConnectionErr);
            yield return(null);
        }
        break;

        default:
        {
            Patcher.Instance.LogString(HobaText.Format("AutoUpdate Failed! {0}", code));
            UpdateInfoUtil.SetCanPlay(false);
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_AutoUpdateErr);
            yield return(null);
        }
        break;
        }

        Patcher.Instance.ReleasePackages();     //释放pck环境
        Patcher.Instance.CleanPatcherTmpDir();  //清除Tmp目录

        yield return(code);
    }
Beispiel #2
0
    private static IEnumerable FetchPackByUrlCoroutine(DownloadMan downloadMan,
                                                       string urlDir, string hostName, string downloadPackName, string strMd5)
    {
        string urlFileName = urlDir + downloadPackName;
        long   dwJupSize   = -1;

        if (dwJupSize <= 0)
        {
            dwJupSize = UpdateUtility.GetUrlFileSizeEx(urlFileName, hostName, DownloadMan.reqTimeOut);
        }

        if (dwJupSize < 0)      //无法取得url文件大小,网络不通重试
        {
            yield return(new WaitForSeconds(1.0f));

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry);
            GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry));
            yield return(null);

            Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to get pack size, file: {0}, host: {1}", urlFileName, hostName));
            yield return(UpdateRetCode.net_err);
        }

        //开始下载
        downloadMan.AddTask(strMd5, urlFileName, hostName, downloadPackName, dwJupSize);
        if (!downloadMan.StartTask(strMd5))
        {
            Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to start download pack, file: {0}", urlFileName));

            yield return(new WaitForSeconds(1.0f));

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry);
            GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry));
            yield return(null);

            Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to start DownloadTask, file: {0}, host: {1}", urlFileName, hostName));
            yield return(UpdateRetCode.net_err);
        }
        else
        {
            Patcher.Instance.LogString(HobaText.Format("DownloadMan StartTask, file: {0}", urlFileName));
        }

        //下载过程
        UpdateInfoUtil.bShowProgress = true;
        DownloadTaskInfo tmpInfo;
        long             taskFinishedSize = 0;
        long             lastFinishedSize = 0;
        int lastTime = System.Environment.TickCount;

        downloadMan.AddDownloadStamp(0, 0);
        int zeroDownloadTime = 0;               //下载量为0的计时,超过10秒无下载量,下载出错重试

        while (downloadMan.IsWorkerRunning())   //
        {
            //Thread.Sleep(100);
            yield return(new WaitForSeconds(0.1f));

            int now     = System.Environment.TickCount;
            int deltaMs = now - lastTime;
            lastTime = now;

            if (downloadMan.FindTask(strMd5, out tmpInfo))
            {
                if (tmpInfo.status.HasError() || tmpInfo.totalSize <= 0.0f)          //下载失败,退出,等待重试
                {
                    yield return(new WaitForSeconds(1.0f));

                    UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry);
                    GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_DownloadingErrAutoRetry));
                    yield return(null);

                    break;
                }

                //更新进度
                {
                    long deltaSize = tmpInfo.finishedSize - lastFinishedSize;

                    if (deltaSize < 10)
                    {
                        zeroDownloadTime += deltaMs;
                    }
                    else
                    {
                        zeroDownloadTime = 0;
                    }

                    downloadMan.AddDownloadStamp(deltaSize, deltaMs);        //下载多少
                    lastFinishedSize = tmpInfo.finishedSize;

                    //新UI
                    CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                    GameUpdateMan.Instance.HotUpdateViewer.SetFileDownloadInfo(
                        updateInfo.curUpdateFileSize + tmpInfo.finishedSize,
                        updateInfo.totalUpdateFileSize,
                        downloadMan.GetDownloadSpeedKBS());

                    float progress = (float)tmpInfo.finishedSize / tmpInfo.totalSize;
                    UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, progress);
                    //                             float totalProgress = (float)(updateInfo.curUpdateFileSize + tmpInfo.finishedSize) / updateInfo.totalUpdateFileSize;
                    //                             UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, totalProgress);

                    if (progress < 1.0f)
                    {
                        UpdateInfoUtil.SetDownStatusString(progress);
                        GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_TextUpdate));
                    }
                    else
                    {
                        zeroDownloadTime = 0;
                        UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_CheckingExistPack);
                        GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_CheckingExistPack));
                    }

                    yield return(null);
                }

                taskFinishedSize = tmpInfo.finishedSize;

                if (zeroDownloadTime >= UpdateConfig.MaxZeroDownloadTime)           //下载为0时间超时
                {
                    break;
                }
            }
            else
            {
                break;              //error
            }
        }
        downloadMan.AddDownloadStamp(0, 0);
        UpdateInfoUtil.bShowProgress = false;

        //这时下载已经完成
        UpdateRetCode ret = UpdateRetCode.success;

        if (Patcher.Instance.IsDownloadDone)
        {
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_CheckingExistPack);
            GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_CheckingExistPack));
            yield return(null);

            if (downloadMan.FindTask(strMd5, out tmpInfo))
            {
                switch (tmpInfo.status)
                {
                case DownloadTaskStatus.Finished:
                    break;

                case DownloadTaskStatus.Failed:
                {
                    DownloadTaskErrorInfo errInfo;
                    downloadMan.GetTaskErrorInfo(strMd5, out errInfo);

                    if (errInfo.errorCode == DownloadTaskErrorCode.NetworkError && errInfo.errorMessage.Contains("CURLE_PARTIAL_FILE"))
                    {
                        ret = UpdateRetCode.net_partial_file;

                        Patcher.Instance.LogString(HobaText.Format("DownloadMan net_partial_file! file: {0}", urlFileName));
                    }
                    else if (errInfo.errorCode == DownloadTaskErrorCode.Unknown && errInfo.errorMessage.Contains("CURLE_OPERATION_TIMEOUTED"))
                    {
                        ret = UpdateRetCode.operation_timeouted;

                        Patcher.Instance.LogString(HobaText.Format("DownloadMan operation_timeouted! file: {0}", urlFileName));
                    }
                    else
                    {
                        if (errInfo.errorCode == DownloadTaskErrorCode.Md5Dismatch)
                        {
                            ret = UpdateRetCode.md5_not_match;
                        }
                        else if (errInfo.errorCode == DownloadTaskErrorCode.NetworkError)
                        {
                            ret = UpdateRetCode.net_err;
                        }
                        else if (errInfo.errorCode == DownloadTaskErrorCode.IOError)
                        {
                            ret = UpdateRetCode.io_err;
                        }
                        else if (errInfo.errorCode == DownloadTaskErrorCode.UrlArgError)
                        {
                            ret = UpdateRetCode.urlarg_error;
                        }
                        else
                        {
                            ret = UpdateRetCode.download_fail;
                        }

                        Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to download pack, file: {0}, host: {1}, msg: {2}", urlFileName, hostName, errInfo.errorMessage));
                    }
                }
                break;

                default:
                    break;
                }
            }
            else
            {
                ret = UpdateRetCode.download_fail;
                Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to download pack 0, file: {0}", urlFileName));
            }
        }
        else
        {
            ret = UpdateRetCode.download_fail;
            Patcher.Instance.LogString(HobaText.Format("DownloadMan fail to download pack 1, file: {0}, zeroDownloadTime: {1}", urlFileName, zeroDownloadTime));
        }

        yield return(ret);
    }
Beispiel #3
0
    //第一阶段更新,取得本地版本和服务器版本,下载服务器版本信息
    public static IEnumerable UpdateCoroutinePhase1()
    {
        //初始化
        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, 0.0f);
        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 0.0f);
        UpdateInfoUtil.SetCanPlay(false);

        //取得本地版本
        UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_TryGetLocalVersion);
        yield return(null);

        var code = Patcher.Instance.GetLocalVersion();

        if (code != UpdateRetCode.success)       //无法取得本地版本
        {
            UpdateInfoUtil.SetCanPlay(false);
            yield return(new WaitForSeconds(1.0f));

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_GetLocalVersionErr);

            Patcher.Instance.LogString("GetLocalVersion Failed!");
            yield return(code);
        }
        else
        {
            //设置本地版本
            UpdateInfoUtil.SetVersion(UPDATE_VERSION.Local, Patcher.Instance.m_CurrentVersion);
        }

        //log
        Patcher.Instance.LogString(HobaText.Format("Client Current Version: {0}", Patcher.Instance.m_CurrentVersion.ToString()));
        Patcher.Instance.LogString(HobaText.Format("FreeDiskSpace: {0}", OSUtility.GetFreeDiskSpace()));

        //检查磁盘空间

        /*
         * UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_TryCheckFreeSpace);
         * yield return null;
         * code = Patcher.Instance.CheckDiskFreeSpace(nCheckFreeSpaceMB * 1024 * 1024);
         * if (code != UpdateRetCode.success)
         * {
         *  UpdateInfoUtil.SetCanPlay(false);
         *  yield return new WaitForSeconds(1.0f);
         *
         *  UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_DiskSpaceFullErr);
         *
         *  Patcher.Instance.LogString("CheckDiskFreeSpace Failed!");
         *  yield return code;
         * }
         */

        //test

        /*
         * string url = "https://www.google.com";
         * string hostName = UpdateUtility.GetHostName(url);
         * string errMsg1;
         * var code1 = UpdateUtility.GetByUrl(url, hostName, System.IO.Path.Combine(EntryPoint.Instance.DocPath, "google.txt"), 10, null, null, out errMsg1);
         * Patcher.Instance.LogString(HobaText.Format("Download Test: {0} {1} {2}", url, code1, errMsg1));
         */

        if (!EntryPoint.Instance.SkipUpdate)             //配置跳过更新
        {
            //DNS解析, 忽略解析错误
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_TryDNSResolving);
            yield return(null);

            string errUpdateServer;
            string errClientServer;
            code = Patcher.Instance.DNSResolving(2, out errUpdateServer, out errClientServer);
            if (!string.IsNullOrEmpty(errUpdateServer))
            {
                Patcher.Instance.LogString("UpdateServer DNSResolving Error : " + errUpdateServer);
            }
            if (!string.IsNullOrEmpty(errClientServer))
            {
                Patcher.Instance.LogString("errClientServer DNSResolving Error : " + errClientServer);
            }

            Patcher.Instance.LogString(string.Format("IP URL UpdateServer1: {0}, UpdateServer2: {1}, UpdateServer3: {2}",
                                                     Patcher.Instance.strUpdateServerDir1, Patcher.Instance.strUpdateServerDir2, Patcher.Instance.strUpdateServerDir3));
            Patcher.Instance.LogString(string.Format("IP URL ClientServer: {0}", Patcher.Instance.strClientServerDir));
            Patcher.Instance.LogString(string.Format("IP URL DynamicServer : {0}", Patcher.Instance.strDynamicServerDir));
            Patcher.Instance.LogString(string.Format("IP URL DynamicAccountRole : {0}", Patcher.Instance.strDynamicAccountRoleDir));

            //从服务器获取version.txt
            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_TryGetNewVersion);
            yield return(null);

            string errMsg    = "";
            string savedFile = Patcher.Instance.strGameNewVerFile;

            DownloadTaskErrorCode dlCode = DownloadTaskErrorCode.Unknown;
            {
                //为了方便部署,内网version.txt用和更新资源jup同一目录,也就是cdn
                if (dlCode != DownloadTaskErrorCode.Success && !string.IsNullOrEmpty(Patcher.Instance.strUpdateServerDir1))
                {
                    string url1      = Patcher.Instance.strUpdateServerDir1 + UpdateConfig.VersionConfigRelativePath;
                    string hostName1 = Patcher.Instance.strUpdateServerHostName1;

                    int nTryConnect = 0;            //尝试多次连接
                    while (dlCode != DownloadTaskErrorCode.Success && nTryConnect < DownloadMan.maxTryConnect)
                    {
                        ++nTryConnect;
                        int timeout = (int)((float)DownloadMan.reqTimeOut * nTryConnect / DownloadMan.maxTryConnect);
                        dlCode = Patcher.Instance.FetchServerVersionFile(url1, hostName1, savedFile, timeout, out errMsg);
                    }
                }

                if (dlCode != DownloadTaskErrorCode.Success && !string.IsNullOrEmpty(Patcher.Instance.strUpdateServerDir2))
                {
                    string url2      = Patcher.Instance.strUpdateServerDir2 + UpdateConfig.VersionConfigRelativePath;
                    string hostName2 = Patcher.Instance.strUpdateServerHostName2;

                    int nTryConnect = 0;            //尝试多次连接
                    while (dlCode != DownloadTaskErrorCode.Success && nTryConnect < DownloadMan.maxTryConnect)
                    {
                        ++nTryConnect;
                        int timeout = (int)((float)DownloadMan.reqTimeOut * nTryConnect / DownloadMan.maxTryConnect);
                        dlCode = Patcher.Instance.FetchServerVersionFile(url2, hostName2, savedFile, DownloadMan.reqTimeOut, out errMsg);
                    }
                }

                if (dlCode != DownloadTaskErrorCode.Success && !string.IsNullOrEmpty(Patcher.Instance.strUpdateServerDir3))
                {
                    string url3      = Patcher.Instance.strUpdateServerDir3 + UpdateConfig.VersionConfigRelativePath;
                    string hostName3 = Patcher.Instance.strUpdateServerHostName3;

                    int nTryConnect = 0;            //尝试多次连接
                    while (dlCode != DownloadTaskErrorCode.Success && nTryConnect < DownloadMan.maxTryConnect)
                    {
                        ++nTryConnect;
                        int timeout = (int)((float)DownloadMan.reqTimeOut * nTryConnect / DownloadMan.maxTryConnect);
                        dlCode = Patcher.Instance.FetchServerVersionFile(url3, hostName3, savedFile, DownloadMan.reqTimeOut, out errMsg);
                    }
                }
            }


            if (dlCode != DownloadTaskErrorCode.Success)
            {
                UpdateInfoUtil.SetCanPlay(false);
                yield return(new WaitForSeconds(1.0f));

                UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_GetNewVersionErr);

                if (dlCode == DownloadTaskErrorCode.Md5Dismatch)
                {
                    code = UpdateRetCode.md5_not_match;
                }
                else
                {
                    code = UpdateRetCode.download_fail;
                }

                Patcher.Instance.LogString("FetchServerVersionFile Failed! DownloadTaskErrorCode: " + dlCode + ": " + errMsg);

                yield return(code);
            }

            //读取游戏新版本信息
            code = Patcher.Instance.TryGetLatestVersionFromServer();
        }
        else
        {
            //读取游戏新版本信息
            code = UpdateRetCode.success;
        }

        if (code != UpdateRetCode.success)
        {
            UpdateInfoUtil.SetCanPlay(false);
            yield return(new WaitForSeconds(1.0f));

            UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateState_GetNewVersionErr);

            Patcher.Instance.LogString("GetVersionMan Failed!");
            yield return(code);
        }
        else
        {
            //设置服务器版本
            UpdateInfoUtil.SetVersion(UPDATE_VERSION.Server, Patcher.Instance.m_VersionMan.VerLastest);
        }

        //log
        Patcher.Instance.LogString(HobaText.Format("Server Version: {0}", Patcher.Instance.m_VersionMan.VerLastest.ToString()));

        UpdateInfoUtil.SetDownloadTotalSize(GameUpdateMan.Instance.GetDownloadTotalSize());

        UpdateInfoUtil.SetCanPlay(false);
        UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_SuccessGetVersions);
        yield return(code);
    }
Beispiel #4
0
    public IEnumerable UpdateAutoCoroutine(ELEMENT_VER verBegin, ELEMENT_VER verLatest)
    {
        long packSizeOverAll = m_VersionMan.CalcSize(verBegin, verLatest);

        if (packSizeOverAll <= 0)
        {
            packSizeOverAll = 1;
        }
        long packFinishedSize = m_VersionMan.CalcSize(verBegin, m_PackFileVer.VerFrom);

        int nTotalPack   = m_VersionMan.CalcPackCount(verBegin, verLatest);
        int nCurrentPack = m_VersionMan.CalcPackCount(verBegin, m_PackFileVer.VerTo);

        GameUpdateMan.Instance.HotUpdateViewer.SetPackageNum(nCurrentPack, nTotalPack);

        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, (float)((double)packFinishedSize / (double)packSizeOverAll));
        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 0.0f);
        UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_BeginUpdate);

        yield return(null);

        UpdateRetCode ret    = UpdateRetCode.success;
        string        strMd5 = this.m_PackFileVer.md5;

        //要下载的路径
        this.strDownloadUPackName = HobaText.Format(
            "{0}-{1}.jup",
            this.m_PackFileVer.VerFrom.ToString(),
            this.m_PackFileVer.VerTo.ToString());
        string strDownloadUPack = this.strDownloadPath + this.strDownloadUPackName;

        //计时
        float nStartTime = Time.time;
        float nLasTime   = nStartTime;
        float nNowTime   = nStartTime;

        //准备下载
        using (DownloadMan downloadMan = new DownloadMan(this.strDownloadPath))              //DownloadMan
        {
            downloadMan.TaskEndEvent += delegate { this.IsDownloadDone = true; };

            int nTryTimes = 0;

            bool bFileEqual = false;
            while (!bFileEqual)
            {
                if (ret == UpdateRetCode.net_err || ret == UpdateRetCode.io_err || ret == UpdateRetCode.urlarg_error)
                {
                    ++nTryTimes;

                    //重连次数超过
                    if (nTryTimes > UpdateConfig.TotalReconnectTime)
                    {
                        ret = UpdateRetCode.connect_fail;
                        break;          //这次更新错误,等待选择重试
                    }

                    //重连,间隔一定时间
                    do
                    {
                        yield return(new WaitForSeconds(1.0f));

                        nNowTime = Time.time;
                    }while (nNowTime - nLasTime <= UpdateConfig.ReconnectTime);
                    nLasTime = nNowTime;

                    this.LogString(HobaText.Format("DownloadMan net_err begin retry {0} ... file: {1}", nTryTimes, this.strDownloadUPackName));
                }
                else
                {
                    nTryTimes = 0;
                }

                if (ret == UpdateRetCode.md5_not_match || ret == UpdateRetCode.download_fail)
                {
                    break;
                }

                //如果文件已存在,判断md5
                if (FileOperate.IsFileExist(strDownloadUPack))
                {
                    yield return(new WaitForSeconds(0.01f));

                    UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 100.0f);
                    UpdateInfoUtil.SetStateString(UPDATE_STATE.UpdateStatus_CheckingExistPack);
                    yield return(null);

                    //string md5_exist = FileOperate.CalcFileMd5(strDownloadUPack);
                    CalcMd5ThreadInfo calcMd5Info = CalcFileMd5(strDownloadUPack);
                    while (calcMd5Info.IsRunning)
                    {
                        yield return(_ShortWait);
                    }
                    OnCalcMd5Complete();
                    string md5_exist = calcMd5Info.Md5;

                    if (md5_exist == strMd5)
                    {
                        bFileEqual = true;
                        break;
                    }
                    FileOperate.DeleteFile(strDownloadUPack);       //删除旧文件
                }

                //重新开始下载
                this.IsDownloadDone = false;
                if (!FileOperate.MakeDir(strDownloadUPack))
                {
                    LogString(HobaText.Format("[UpdateAutoCoroutine] MakeDir {0} Failed!", strDownloadUPack));
                }

                //
                UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 0.0f);
                UpdateInfoUtil.SetDownStatusString(0.0f);
                GameUpdateMan.Instance.HotUpdateViewer.SetDownloadInfo_TextUpate(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_TextUpdate));

                yield return(null);

//              foreach (var item in FetchPackByUrlCoroutine(downloadMan,
//                     this.strUpdateServerDir1, this.strUpdateServerHostName1, this.strDownloadUPackName, strMd5))
                foreach (var item in FetchPackCoroutine(downloadMan,
                                                        this.strUpdateServerDir1, this.strUpdateServerHostName1,
                                                        this.strUpdateServerDir2, this.strUpdateServerHostName2,
                                                        this.strUpdateServerDir3, this.strUpdateServerHostName3,
                                                        this.strDownloadUPackName, strMd5))
                {
                    if (item is UpdateRetCode)
                    {
                        ret = (UpdateRetCode)item;
                        break;
                    }
                    else
                    {
                        yield return(item);
                    }
                }

                if (ret != UpdateRetCode.success)
                {
                    bFileEqual = false;
                }
            }

            if (bFileEqual)
            {
                ret = UpdateRetCode.success;
            }
        }

        if (ret == UpdateRetCode.success)        //下载成功
        {
            UpdateInfoUtil.bShowWritingPack = true;

            //设置本地包路径
            strLocalPackFileName = strDownloadPath + strDownloadUPackName;
            UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 0.0f);

            yield return(null);

            //打开本地包,更新...
            //提示正在写包
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallInfo(UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_WritingPack));
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallPercent(-1.0f);

            foreach (var item in UpdateFileFromPackCoroutine(strLocalPackFileName, verBegin, verLatest))
            {
                if (item is UpdateRetCode)
                {
                    ret = (UpdateRetCode)item;
                    break;
                }

                yield return(item);
            }

            //关闭临时包
            FileOperate.DeleteFile(this.strLocalPackFileName);
            this.strLocalPackFileName = "";

            UpdateInfoUtil.bShowWritingPack = false;
        }

        if (ret == UpdateRetCode.invalid_param)
        {
            ret = UpdateRetCode.cancel;
            yield return(ret);
        }
        else if (ret == UpdateRetCode.pack_file_broken ||
                 ret == UpdateRetCode.net_err ||
                 ret == UpdateRetCode.connect_fail ||
                 ret == UpdateRetCode.md5_not_match ||
                 ret == UpdateRetCode.io_err ||
                 ret == UpdateRetCode.urlarg_error ||
                 ret == UpdateRetCode.download_fail)
        {
            yield return(ret);
        }
        else if (ret != UpdateRetCode.success)
        {
            ret = UpdateRetCode.fail;
            yield return(ret);
        }

        //写入本地版本
        UpdateInfoUtil.SetVersion(UPDATE_VERSION.Local, this.m_CurrentVersion);

        yield return(UpdateRetCode.success);
    }