コード例 #1
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //解析服务器版本信息
    public UpdateRetCode TryGetLatestVersionFromServer()
    {
        UpdateRetCode code = UpdateRetCode.success;

        try
        {
            StreamReader reader = FileOperate.OpenTextFile(strGameNewVerFile);
            if (reader == null)
            {
                return(UpdateRetCode.patcher_no_ver_file);
            }

            if (!m_VersionMan.LoadVersions(reader))
            {
                reader.Close();
                code = UpdateRetCode.patcher_invalid_ver_file;
                FileOperate.DeleteFile(strGameNewVerFile);
            }
            else
            {
                reader.Close();
            }
        }
        catch (Exception)
        {
            code = UpdateRetCode.patcher_ver_err;
        }


        return(code);
    }
コード例 #2
0
    protected override UpdateRetCode onUpdate(uint elapsed)
    {
        UpdateRetCode ret = base.onUpdate(elapsed);

        if (ret != UpdateRetCode.Continue)
        {
            return(ret);
        }

        Vector3 targetPosition = Vector3.zero;

        if (!mController.Update(elapsed, AbsoluteSpeed, out targetPosition))
        {
            ret = UpdateRetCode.Finished;
        }

        if (mOwner.Scene.IsBarrierRegion(mOwner, targetPosition.x, targetPosition.z))
        {
            ret = UpdateRetCode.Aborted;
        }
        else
        {
            mOwner.SetPosition(targetPosition);
        }

        return(ret);
    }
コード例 #3
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //关闭pck环境
    public UpdateRetCode ReleasePackages()
    {
        UpdateRetCode code = UpdateRetCode.success;

        PackFunc.PackFinalize(true);
        return(code);
    }
コード例 #4
0
    public void UpdateSkillEffects(uint elapsed)
    {
        // 构造临时容器, 更新之中的元素.
        // 因为在Update和Stop一个SkillEffect时, 可能产生新的SkillEffect加入到mContainer中,
        // 因此只遍历当前容器内的元素.
        int count = mContainer.Count;

        for (int i = 0; i < count; ++i)
        {
            SkillEffect effect = mContainer[i];
            if (!effect.IsAwake)
            {
                continue;
            }

            UpdateRetCode retCode = effect.Update(elapsed);
            if (retCode != UpdateRetCode.Continue)
            {
                // effect从运行状态开始, 经过Update之后, 不在工作, 原因只可能是
                // 时间结束或者在Update中, 被终止(不可能被回收).
                effect.Stop(retCode == UpdateRetCode.Finished
                                        ? SkillEffectStopReason.Expired : SkillEffectStopReason.Diffused
                            );
            }
        }

        mContainer.RemoveAll(x => (!x.IsAwake));
    }
コード例 #5
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //初始化pck环境
    public UpdateRetCode InitPackages()
    {
        UpdateRetCode code = UpdateRetCode.success;

        bool ret = PackFunc.PackInitialize(false);

        if (!ret)
        {
            code = UpdateRetCode.pack_err;
        }

        return(code);
    }
コード例 #6
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //如果本地文件不存在,设置为初始版本, 如果当前版本 < 初始版本,则写新版本, ret是否新写入baseVersion
    public bool SetFirstVersion(ELEMENT_VER ver, bool bForceWrite)
    {
        m_baseVer = ver;

        if (bForceWrite || !FileOperate.IsFileExist(strGameOldVerFile))
        {
            if (!FileOperate.MakeDir(strGameOldVerFile))
            {
                LogString(HobaText.Format("[SetFirstVersion] MakeDir {0} Failed!", strGameOldVerFile));
            }
            UpdateRetCode ret = SetLocalVersion(ver);
            if (ret != UpdateRetCode.success)
            {
                LogString(HobaText.Format("[SetFirstVersion] SetLocalVersion {0} Failed!", strGameOldVerFile));
            }
            else
            {
                return(true);
            }
        }
        else
        {
            ELEMENT_VER localVersion;
            if (GetLocalVersion(out localVersion) && localVersion < m_baseVer)
            {
                LogString(HobaText.Format("[SetFirstVersion] Local Version File Exist {0}! Write New Version From: {1} To {2}", strGameOldVerFile, localVersion.ToString(), ver.ToString()));

                if (!FileOperate.MakeDir(strGameOldVerFile))
                {
                    LogString(HobaText.Format("[SetFirstVersion] MakeDir {0} Failed2!", strGameOldVerFile));
                }
                UpdateRetCode ret = SetLocalVersion(ver);
                if (ret != UpdateRetCode.success)
                {
                    LogString(HobaText.Format("[SetFirstVersion] SetLocalVersion {0} Failed2!", strGameOldVerFile));
                }
                else
                {
                    return(true);
                }
            }
            else
            {
                LogString(HobaText.Format("[SetFirstVersion] Local Version File Exist {0}!", strGameOldVerFile));
            }
        }

        return(false);
    }
コード例 #7
0
    protected override UpdateRetCode onUpdate(uint elapsed)
    {
        Vector3 oldPosition = mOwner.GetPosition();

        UpdateRetCode ret = base.onUpdate(elapsed);

        if (ret != UpdateRetCode.Aborted)
        {
            if (mTargetSelectionOnExecute != null)
            {
                displacementCollide(oldPosition, mQuickMoveDirection, Utility.Distance2D(mOwner.GetPosition(), oldPosition));
            }
        }

        return(ret);
    }
コード例 #8
0
    override protected UpdateRetCode onUpdate(uint elapsed)
    {
        if (mState == ActionSkillState.Invalid)
        {
            return(UpdateRetCode.Aborted);
        }

        uint skillResID = dbgSkillResId;

        mTaskManager.Update(elapsed);

        // 技能效果可能把技能自身中断.
        if (mState == ActionSkillState.Invalid)
        {
            GameDebug.Log("skill " + skillResID + " interrupted by itself");
            return(UpdateRetCode.Aborted);
        }

        UpdateRetCode retCode = UpdateRetCode.Continue;

        mStateTimer += elapsed;

        switch (mState)
        {
        case ActionSkillState.Charging:
            // 如果过了准备时间, 那么进入使用状态.
            if (mStateTimer > mSkillUsing.skillRes.chargeTime)
            {
                ErrorCode ec = EnterUseState(SkillTargetPosition);
                if (ec != ErrorCode.Succeeded)
                {
                    retCode = UpdateRetCode.Aborted;
                }
            }
            break;

        case ActionSkillState.Using:
            if (mSkillUseStateLoopLeft == 0)
            {
                retCode = UpdateRetCode.Finished;
            }
            break;
        }

        return(retCode);
    }
コード例 #9
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //找到版本pair
    public UpdateRetCode FindVersionPair()
    {
        UpdateRetCode code = UpdateRetCode.success;

        VER_PAIR verPair;
        bool     bFind = m_VersionMan.FindVersionPair(m_CurrentVersion, out verPair);

        if (!bFind)
        {
            code = UpdateRetCode.patcher_no_ver_file;
        }
        else
        {
            m_PackFileVer = verPair;
        }

        return(code);
    }
コード例 #10
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    //更新服务器列表
    public static UpdateRetCode ParseServerList(string serverListFile, List <ServerInfo> serverList)
    {
        UpdateRetCode code = UpdateRetCode.success;

        try
        {
            StreamReader reader = FileOperate.OpenTextFile(serverListFile);
            if (reader == null)
            {
                return(UpdateRetCode.server_list_no_file);
            }

            string text = reader.ReadToEnd();
            reader.Close();

            string ext = Path.GetExtension(serverListFile);
            if (ext != null && ext.ToLower() == ".xml")
            {
                if (!ServerInfo.ParseFromXmlString(text, serverList))
                {
                    code = UpdateRetCode.server_list_parse_err;
                }
            }
            else if (ext != null && ext.ToLower() == ".json")
            {
                if (!ServerInfo.ParseFromJsonString(text, serverList))
                {
                    code = UpdateRetCode.server_list_parse_err;
                }
            }
            else
            {
                code = UpdateRetCode.server_list_parse_err;
                FileOperate.DeleteFile(serverListFile);
            }
        }
        catch (Exception)
        {
            code = UpdateRetCode.server_list_parse_err;
        }

        return(code);
    }
コード例 #11
0
    /// <summary>
    /// 更新每个Action, Action的实际清除操作统一在这里进行.
    /// </summary>
    public void UpdateActions(uint elapsed)
    {
        for (ActionTypeDef type = ActionTypeDef.ActionTypeIdle; type < ActionTypeDef.ActionTypeCount; ++type)
        {
            Action action = mActionContainer[(int)type];
            if (action == null)
            {
                continue;
            }

            if (!action.IsRunning)
            {
                mActionContainer[(int)type] = null;
                continue;
            }

            UpdateRetCode ret = action.Update(elapsed);
            if (ret != UpdateRetCode.Continue)
            {
                action.Stop((ret == UpdateRetCode.Finished));
                mActionContainer[(int)type] = null;
            }
        }
    }
コード例 #12
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);
    }
コード例 #13
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    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);
    }
コード例 #14
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    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);
    }
コード例 #15
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    public UpdateRetCode ReadIncFileList(string strFile, out FileIncList fileIncList, out ELEMENT_VER newVer)
    {
        UpdateRetCode ret = UpdateRetCode.success;

        newVer      = new ELEMENT_VER();
        fileIncList = new FileIncList();

        using (StreamReader reader = FileOperate.OpenTextFile(strFile))
        {
            ELEMENT_VER verFrom = new ELEMENT_VER();
            ELEMENT_VER verTo   = new ELEMENT_VER();

            //read header
            //"# %d.%d.%d %d.%d.%d %s %d"
            try
            {
                var strLine = reader.ReadLine();
                if (string.IsNullOrEmpty(strLine))
                {
                    return(UpdateRetCode.patcher_invalid_ver_file);
                }

                char[] split = { ' ', '\t' };
                {
                    var arr = strLine.Split(split);
                    if (arr.Length >= 5 && arr[0] == "#")
                    {
                        verFrom.Parse(arr[1]);
                        verTo.Parse(arr[2]);
                        //projName = arr[3];
                        //nUpdateSize = Int32.Parse(arr[4]);
                    }
                    else
                    {
                        return(UpdateRetCode.patcher_invalid_ver_file);
                    }
                }

                //检查版本
                if (m_CurrentVersion < verFrom)
                {
                    return(UpdateRetCode.patcher_version_too_new);
                }

                if (m_CurrentVersion > verTo || m_CurrentVersion == verTo)
                {
                    return(UpdateRetCode.patcher_version_too_old);
                }

                newVer = verTo;         //设置新版本

                while (true)
                {
                    strLine = reader.ReadLine();
                    if (strLine == null)
                    {
                        break;
                    }

                    if (strLine[0] == '#')
                    {
                        continue;
                    }

                    var arr = strLine.Split(split);
                    if (arr.Length >= 2)
                    {
                        string md5      = arr[0];
                        string filename = arr[1];
                        fileIncList.AddFile(md5, filename);
                    }
                    else
                    {
                        return(UpdateRetCode.patcher_invalid_ver_file);
                    }
                }
            }
            catch (Exception)
            {
                return(UpdateRetCode.fail);
            }
        }
        return(ret);
    }
コード例 #16
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    private static IEnumerable FetchPackCoroutine(DownloadMan downloadMan,
                                                  string urlDir1, string hostName1, string urlDir2, string hostName2, string urlDir3, string hostName3,
                                                  string downloadPackName, string strMd5)
    {
        UpdateRetCode code = UpdateRetCode.success;

        foreach (var item in FetchPackByUrlCoroutine(downloadMan, urlDir1, hostName1, downloadPackName, strMd5))
        {
            if (item is UpdateRetCode)
            {
                code = (UpdateRetCode)item;
                break;
            }
            else
            {
                yield return(item);
            }
        }

        if (code == UpdateRetCode.success || code == UpdateRetCode.net_partial_file || code == UpdateRetCode.operation_timeouted)
        {
            yield return(code);
        }

        code = UpdateRetCode.success;

        foreach (var item in FetchPackByUrlCoroutine(downloadMan, urlDir2, hostName2, downloadPackName, strMd5))
        {
            if (item is UpdateRetCode)
            {
                code = (UpdateRetCode)item;
                break;
            }
            else
            {
                yield return(item);
            }
        }

        if (code == UpdateRetCode.success || code == UpdateRetCode.net_partial_file || code == UpdateRetCode.operation_timeouted)
        {
            yield return(code);
        }

        //下载第三个url
        code = UpdateRetCode.success;

        foreach (var item in FetchPackByUrlCoroutine(downloadMan, urlDir3, hostName3, downloadPackName, strMd5))
        {
            if (item is UpdateRetCode)
            {
                code = (UpdateRetCode)item;
                break;
            }
            else
            {
                yield return(item);
            }
        }

        yield return(code);
    }
コード例 #17
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    public IEnumerable UpdateFileFromPackCoroutine(string strPackFile, ELEMENT_VER verBegin, ELEMENT_VER verLatest)
    {
        UpdateRetCode code = UpdateRetCode.success;

        if (this.m_CurrentVersion.IsValid())
        {
            code = GetLocalVersion();
            if (code != UpdateRetCode.success)
            {
                yield return(UpdateRetCode.element_ver_err);
            }
        }

        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 0.0f);
        UpdateInfoUtil.SetWritingPackStatusString(0.0f);

        //新UI
        GameUpdateMan.Instance.HotUpdateViewer.SetInstallPercent(-1);

        yield return(null);

        //code = DoUpdateFrom7z(strPackFile);
        foreach (var item in this.DoUpdateFrom7zCoroutine(strPackFile, verBegin, verLatest))
        {
            if (item is UpdateRetCode)
            {
                code = (UpdateRetCode)item;
                break;
            }
            yield return(null);
        }

        if (code != UpdateRetCode.success)
        {
            FileOperate.DeleteFile(strUpdateIncFile); //删除inc.sw文件
        }
        else                                          //更新成功,写新版本
        {
            if (m_currentNewVer < BaseVersion)
            {
                code = UpdateRetCode.patcher_version_too_old;
            }
            else
            {
                ELEMENT_VER newVer = m_currentNewVer;
                UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, 1.0f);
                //UpdateInfoUtil.SetWritingPackStatusString(1.0f);

                //新UI
                //GameUpdateMan.Instance.HotUpdateViewer.SetInstallPercent(1.0f);

                yield return(null);

                long sizeAdd = this.m_VersionMan.CalcSize(m_CurrentVersion, m_currentNewVer);
                UpdateInfoUtil.AddDownloadedSize(sizeAdd);

                //更新本地版本
                SetLocalVersion(newVer);
                m_CurrentVersion = newVer;

                VER_PAIR verPair = m_PackFileVer;           //更新m_PackFileVer,避免重复下载,下一个版本pair需要FindVersionPair
                verPair.VerTo   = newVer;
                verPair.VerFrom = newVer;
                m_PackFileVer   = verPair;
            }
        }

        yield return(code);
    }
コード例 #18
0
ファイル: Patcher2.cs プロジェクト: frozen4/UnityPlus
    public IEnumerable DoUpdateFrom7zCoroutine(string strPack, ELEMENT_VER verBegin, ELEMENT_VER verLatest)
    {
        //this.LogString(HobaText.Format("DoUpdateFrom7zCoroutine: {0}, {1}, {2}", strPack, verBegin.ToString(), verLatest.ToString()));

        UpdateRetCode code = UpdateRetCode.success;

        SevenZReader reader = new SevenZReader();

        if (!reader.Init(strPack))
        {
            code = UpdateRetCode.pack_file_broken;
            reader.Release();
            yield return(code);            //
        }

        int fileCount = reader.GetFileCount();

        if (fileCount > 0)
        {
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallProgress(1, fileCount);
            yield return(null);
        }

        FileIncList fileIncList = new FileIncList();
        //找到7z包中的版本文件, inc, 得到版本
        bool bIncValid = false;

        for (int iFile = 0; iFile < fileCount; ++iFile)
        {
            string name = reader.GetFileName(iFile);

            //            LogString(HobaString.Format("7z pack file: {0}: {1}", iFile, name));
            if (name == "")
            {
                this.LogString(HobaText.Format("Fail to get file name: {0}", iFile));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);        //
            }

            if (!bIncValid && name == "inc")
            {
                bIncValid = true;

                //读取
                ExtractPackThreadInfo threadInfo = ExtractFileFrom7zReader(reader, iFile);
                while (threadInfo.IsRunning)
                {
                    yield return(_ShortWait);
                }
                OnExtractFileComplete();

                int    dataSize = threadInfo.DataSize;
                IntPtr pData    = threadInfo.Pointer;
                if (pData == IntPtr.Zero)
                {
                    this.LogString(HobaText.Format("Fail to extract file name: {0}", iFile));
                    code = UpdateRetCode.pack_file_broken;
                    reader.Release();
                    yield return(code);    //
                }

                //写入
                if (!FileOperate.MakeDir(this.strUpdateIncFile))
                {
                    LogString(HobaText.Format("[UpdateAutoCoroutine] MakeDir {0} Failed!", this.strUpdateIncFile));
                }

                byte[] pText = new byte[dataSize];
                Marshal.Copy(pData, pText, 0, dataSize);
                char[] text = Encoding.UTF8.GetChars(pText);
                bool   ret  = FileOperate.WriteToTextFile(this.strUpdateIncFile, text, text.Length);

                if (!ret)
                {
                    this.LogString(HobaText.Format("Fail to write inc file name: %d", iFile));
                    code = UpdateRetCode.file_write_err;
                    reader.Release();
                    yield return(code);    //
                }

                //读取inc内容
                code = ReadIncFileList(this.strUpdateIncFile, out fileIncList, out m_currentNewVer);
                //删除本地inc文件
                FileOperate.DeleteFile(this.strUpdateIncFile);
            }

            if (bIncValid)
            {
                break;
            }
        }

        if (!bIncValid || code != UpdateRetCode.success)          //找不到inc文件
        {
            this.LogString("Pack has no list file: " + strPack);
            code = UpdateRetCode.pack_file_broken;
            reader.Release();
            yield return(code);    //
        }

        //计算进度
        long packSizeOverAll = m_VersionMan.CalcSize(verBegin, verLatest);

        if (packSizeOverAll <= 0)
        {
            packSizeOverAll = 1;
        }
        long packFinishedSize   = m_VersionMan.CalcSize(verBegin, m_CurrentVersion);
        long packNextFinishSize = m_VersionMan.CalcSize(verBegin, m_currentNewVer);

        float fFileProgress  = 0.0f;
        float fTotalProgress = (float)((packFinishedSize + (packNextFinishSize - packFinishedSize) * (double)fFileProgress) / (double)packSizeOverAll);

        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, fFileProgress);
        UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, fTotalProgress);
        //UpdateInfoUtil.SetWritingPackStatusString(fFileProgress);

        //新UI
        fileCount = reader.GetFileCount();
        if (fileCount > 0)
        {
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallProgress(1, fileCount);
        }
        else
        {
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallPercent(-1.0f);
        }

        yield return(null);

        //读取patch文件列表
        for (int iFile = 0; iFile < fileCount; ++iFile)
        {
            //新UI
            GameUpdateMan.Instance.HotUpdateViewer.SetInstallProgress(iFile + 1, fileCount);
            yield return(null);

            if (reader.IsDir(iFile))
            {
                continue;
            }

            string name = reader.GetFileName(iFile);

            //            LogString(HobaString.Format("7z pack file: {0}: {1}", iFile, name));
            if (string.IsNullOrEmpty(name))
            {
                this.LogString(HobaText.Format("Fail to get file name: {0}", iFile));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);    //
            }

            if (name == "inc")      //skip inc
            {
                continue;
            }

            string strMd5;
            if (!fileIncList.GetFileMd5(name, out strMd5))
            {
                this.LogString(HobaText.Format("Fail to get file md5: {0} {1}", iFile, name));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);        //
            }

            bool bInPack        = PackFunc.IsFileInPack(name); //是否属于指定的包
            bool bSameFileExist = false;

            if (bInPack)         //在包里的文件是否和更新文件md5一致,如果是则跳过更新
            {
                if (PackFunc.CalcPackFileMd5(name) == strMd5)
                {
                    bSameFileExist = true;
                }
            }
            if (bSameFileExist)
            {
                //if (iFile % (10 * 3) == 0)
                {
                    fFileProgress  = (float)(iFile + 1) / fileCount;
                    fTotalProgress = (float)(packFinishedSize + (packNextFinishSize - packFinishedSize) * fFileProgress) / packSizeOverAll;

                    UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.File, fFileProgress);
                    UpdateInfoUtil.SetProgress(UPDATE_PROGRESS.Total, fTotalProgress);
                    //UpdateInfoUtil.SetWritingPackStatusString(fFileProgress);
                    GameUpdateMan.Instance.HotUpdateViewer.SetInstallProgress(fileCount, fileCount);

                    yield return(null);
                }
                continue;
            }

            //读取patch文件
            ExtractPackThreadInfo threadInfo = ExtractFileFrom7zReader(reader, iFile);
            while (threadInfo.IsRunning)
            {
                yield return(_ShortWait);
            }
            OnExtractFileComplete();

            int    dataSize = threadInfo.DataSize;
            IntPtr pData    = threadInfo.Pointer;

            if (pData == IntPtr.Zero)
            {
                this.LogString(HobaText.Format("Fail to extract file name: {0}", iFile));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);        //
            }

            //检查md5
            //string memMd5 = FileOperate.CalcMemMd5(pData, dataSize);
            CalcMd5ThreadInfo calcMd5Info = CalcMemMd5(pData, dataSize);
            while (calcMd5Info.IsRunning)
            {
                yield return(_ShortWait);
            }
            OnCalcMd5Complete();
            string memMd5 = calcMd5Info.Md5;

            if (memMd5 != strMd5)
            {
                this.LogString(HobaText.Format("File md5 mismatch: {0} {1}", iFile, name));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);        //
            }

            if (dataSize < 4)        //不是压缩文件
            {
                this.LogString(HobaText.Format("Compressed file has no header {0} {1}", iFile, name));
                code = UpdateRetCode.pack_file_broken;
                reader.Release();
                yield return(code);        //
            }

            if (bInPack) //add to package
            {
                this.WritePacking(true);
                bool retFlag = PackFunc.AddCompressedDataToPack(name, pData, dataSize);

                if (!retFlag)
                {
                    this.LogString(HobaText.Format("Update fail to add file: {0} {1}", iFile, name));
                    code = UpdateRetCode.pack_file_broken;
                    reader.Release();
                    yield return(code);        //
                }
                else
                {
                    //                  this.LogString(HobaString.Format("Success to add pack file: {0} {1}", iFile, name));
                    code = UpdateRetCode.success;
                }
            }
            else                   //解压,写文件
            {
                //使用更新目录, 将 AssetBundle/<Plaform> 和 AssetBundle/<Plaform>/Update 整合成AssetBundle
                string actualName;
                if (PackFunc.IsFileInAssetBundles(name))
                {
                    actualName = PackFunc.MakeShortAssetBundlesFileName(name);
                    //                    this.LogString(HobaString.Format("MakeShortAssetBundlesFileName: {0} {1} TO {2}", iFile, name, actualName));
                }
                else
                {
                    actualName = name;
                }

                UncompressToSepFileThreadInfo uncompressInfo = UncompressToSepFile(actualName, pData, dataSize);
                while (uncompressInfo.IsRunning)
                {
                    yield return(_ShortWait);
                }
                OnUncompressToSepFileComplete();

                bool retFlag = uncompressInfo.RetFlag;
                if (!retFlag)
                {
                    this.LogString(HobaText.Format("Update fail to uncompress file: {0} {1}", iFile, actualName));
                    code = UpdateRetCode.pack_file_broken;
                    reader.Release();
                    yield return(code);        //
                }
                else
                {
                    //                  this.LogString(HobaString.Format("Success to add sep file: {0} {1}", iFile, name));
                    code = UpdateRetCode.success;
                }
            }
        }

        reader.Release();

        PackFunc.FlushWritePack();
        if (!PackFunc.SaveAndOpenUpdatePack())
        {
            this.LogString(HobaText.Format("PackFunc.SaveAndOpenUpdatePack() Failed!!! {0}", strPack));
        }
        else
        {
            this.WritePacking(false);       //清除写包标志
        }

        yield return(code);        //
    }
コード例 #19
0
ファイル: GameUpdateMan.cs プロジェクト: frozen4/UnityPlus
    public IEnumerable UpdateRoutine()
    {
        //检查系统内存

        /*
         * if (SystemInfo.systemMemorySize < nMemoryMinimum)
         * {
         *  yield return new WaitForUserClick(MessageBoxStyle.MB_YesNo,
         *          HobaText.Format(EntryPoint.Instance.UpdateStringConfigParams.SystemRequire_Memory, nMemoryMinimum),
         *          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError));
         *
         *  if (WaitForUserClick.RetCode == 0)
         *  {
         *      Patcher.Instance.UpdateExit();
         *      EntryPoint.ExitGame();
         *      yield break;
         *  }
         * }
         * */

        LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update); //平台SDK打点:检查更新

        yield return(null);

        //更新资源,测试
        {
            string baseDir = EntryPoint.Instance.ResPath;
            string docDir  = EntryPoint.Instance.DocPath;
            string libDir  = EntryPoint.Instance.LibPath;
            string tmpDir  = EntryPoint.Instance.TmpPath;

            string updateServerDir1      = EntryPoint.Instance.GetUpdateServerUrl1();
            string updateServerDir2      = EntryPoint.Instance.GetUpdateServerUrl2();
            string updateServerDir3      = EntryPoint.Instance.GetUpdateServerUrl3();
            string clientServerDir       = EntryPoint.Instance.GetClientServerUrl();
            string dynamicServerDir      = EntryPoint.Instance.GetDynamicServerUrl();
            string dynamicAccountRoleDir = EntryPoint.Instance.GetDynamicAccountRoleUrl();

            foreach (var item in Patcher.Instance.Init(baseDir, docDir, libDir, tmpDir,
                                                       updateServerDir1, updateServerDir2, updateServerDir3, clientServerDir, dynamicServerDir, dynamicAccountRoleDir))
            {
                yield return(item);
            }

            //设置初始版本
#if  UNITY_EDITOR //|| UNITY_STANDALONE_WIN
            Patcher.Instance.CleanAllUpdatesReturnToBase(Patcher.Instance.BaseVersion);
#else
            string baseVersion   = CPlatformConfig.GetBaseVersion();
            bool   bWriteVersion = Patcher.Instance.SetFirstVersion(baseVersion, false);
            if (bWriteVersion)
            {
                Patcher.Instance.CleanAllUpdatesReturnToBase(Patcher.Instance.BaseVersion);
            }
#endif

            bool          bSkipPhase2 = false;
            UpdateRetCode retCode     = UpdateRetCode.success;

UpdateStartPhase1:
            //阶段1...
            int nTryTime = 0;
            do
            {
                _HotUpdateViewer.SetInstallPercent(-1.0f);

                foreach (var item in Patcher.UpdateCoroutinePhase1())
                {
                    CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                    _HotUpdateViewer.SetPartProgress(updateInfo.curUpdateProgress);
                    _HotUpdateViewer.SetAllProgress(updateInfo.totalUpdateProgress);
                    _HotUpdateViewer.SetDesc(updateInfo.strUpdateInfo);

                    //新UI
                    _HotUpdateViewer.SetCurrentVersion(updateInfo.curVersion);
                    _HotUpdateViewer.SetServerVersion(updateInfo.serverVersion);

                    yield return(null);

                    if (item is UpdateRetCode)
                    {
                        retCode = (UpdateRetCode)item;
                        break;
                    }

                    yield return(item);
                }

                m_CurrentVersion = Patcher.Instance.m_CurrentVersion.ToString();
                m_ServerVersion  = Patcher.Instance.m_VersionMan.VerLastest.ToString();

                if (retCode != UpdateRetCode.success)               //错误处理
                {
                    if (nTryTime == 0)
                    {
                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_NetworkErr),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError)));

                        UpdateInfoUtil.SetCanPlay(false);    //重试
                    }
                    else
                    {
                        LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败

                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_NetConnectionErr),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError)));

#if !UNITY_EDITOR
                        Patcher.Instance.UpdateExit();
                        EntryPoint.ExitGame();
                        yield break;
#else                                                            //忽略错误,直接游戏
                        retCode     = UpdateRetCode.success;
                        bSkipPhase2 = true;
                        break;
#endif
                    }

                    ++nTryTime;
                }
                else                 //成功
                {
                    if (IsVersionCanUpdate() && !IsVersionComplete())
                    {
                        long   downloadSize = GetDownloadTotalSize();
                        string num          = string.Empty;
                        float  fMB          = downloadSize / (1024.0f * 1024.0f);
                        if (fMB >= 1f)
                        {
                            fMB = ((fMB * 10) - (fMB * 10) % 1) / 10; //保留一位小数
                            if (fMB % 1 > 0)
                            {
                                //有小数点
                                num = HobaText.Format("{0:0.0} MB", fMB);
                            }
                            else
                            {
                                num = HobaText.Format("{0:0} MB", fMB);
                            }
                        }
                        else
                        {
                            float fKB = downloadSize / 1024.0f;
                            num = HobaText.Format("{0:0} KB", fKB);
                        }

                        //下载总量提示
                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OkCancel,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateState_DownloadCheck),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_BeginUpdate),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_WifiTips),
                                                          num));

                        if (WaitForUserClick.RetCode == 0)
                        {
                            LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败
                            Patcher.Instance.UpdateExit();
                            EntryPoint.ExitGame();
                            yield break;
                        }

                        //存储空间检查,提示
                        long lDiskSize = OSUtility.GetFreeDiskSpace();
                        long lNeedSize = (long)(downloadSize * fExtraSpace) + 100 * 1024 * 1024;

                        Patcher.Instance.LogString(HobaText.Format("CheckDownloadSize! FreeDiskSize: {0}, NeedSize: {1}", lDiskSize, lNeedSize));

                        if (lDiskSize != 0 && lDiskSize < lNeedSize)
                        {
                            LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败

                            long   iNeedSizeMB       = lNeedSize / (1024 * 1024);
                            string strNoSpaceMessage = HobaText.Format(EntryPoint.Instance.UpdateStringConfigParams.SystemRequire_Space, iNeedSizeMB);
                            yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                              strNoSpaceMessage,
                                                              UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalError)));

                            Patcher.Instance.UpdateExit();
                            EntryPoint.ExitGame();
                            yield break;
                        }

                        _HotUpdateViewer.StartPromotion();
                    }
                    break;              //确认下载,进入下一阶段
                }
            } while (true);

            if (!bSkipPhase2 && retCode == UpdateRetCode.success)
            {
                yield return(new WaitForSeconds(0.2f));

                if (!IsVersionComplete() && !bWifiMsgBoxShow)           //需要下载更新包,如果不是wifi需要提示
                {
                    if (OSUtility.IsNetAvailable() && !OSUtility.IsWifi())
                    {
                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OkCancel,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasErrorNotWifi),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError)));

                        bWifiMsgBoxShow = true;

                        if (WaitForUserClick.RetCode == 0)
                        {
                            LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败
                            Patcher.Instance.UpdateExit();
                            EntryPoint.ExitGame();
                            yield break;
                        }
                        //继续
                    }
                }

                //阶段2...
                do
                {
                    foreach (var item in Patcher.UpdateCoroutinePhase2())
                    {
                        CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                        _HotUpdateViewer.SetPartProgress(updateInfo.curUpdateProgress);
                        _HotUpdateViewer.SetAllProgress(updateInfo.totalUpdateProgress);
                        _HotUpdateViewer.SetDesc(updateInfo.strUpdateInfo);
                        _HotUpdateViewer.SetCurrentVersion(updateInfo.curVersion);
                        _HotUpdateViewer.SetServerVersion(updateInfo.serverVersion);

                        yield return(null);

                        if (item is UpdateRetCode)
                        {
                            retCode = (UpdateRetCode)item;
                            break;
                        }
                        else
                        {
                            yield return(item);
                        }
                    }

                    if (retCode == UpdateRetCode.pack_err ||                  //包错误, 严重错误,需要清空所有更新目录重试
                        retCode == UpdateRetCode.pack_open_err ||
                        retCode == UpdateRetCode.pack_read_err ||
                        retCode == UpdateRetCode.pack_write_err)
                    {
                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalErrorNeedCleanUp),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalError)));

                        yield return(new WaitForSeconds(1.0f));

                        //上次写包错误,这时需要删除所有更新包,从基础版本重新更新,待测试
                        Patcher.Instance.CleanAllUpdatesReturnToBase(Patcher.Instance.BaseVersion);
                        UpdateInfoUtil.SetCanPlay(false);    //重试

                        yield return(new WaitForSeconds(1.0f));

                        goto UpdateStartPhase1;                                //重新开始更新,阶段1
                    }
                    else if (retCode == UpdateRetCode.patcher_version_too_new) //版本太老,不能通过自动更新解决, 需要重新下载程序
                    {
                        _HotUpdateViewer.SetCircle(false);
#if UNITY_STANDALONE_WIN
                        //FIXME:: 原逻辑版本不一致都不能进入游戏, 策划需求Windows 特殊处理点取消进入游戏,忽略程序版本限制
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OkCancel,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalErrorNeedReinstall),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_BeginUpdate)));

                        if (WaitForUserClick.RetCode == 0)
                        {
                            retCode = UpdateRetCode.success;       //走Phase3
                            break;
                        }
                        else
                        {
                            Patcher.Instance.UpdateExit();
                            EntryPoint.ExitGame();
                            yield break;
                        }
#else
                        //FIXME:: 原逻辑
                        LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败
#if PLATFORM_KAKAO
                        while (true)
                        {
                            yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                              UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalErrorNeedReinstall),
                                                              UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_BeginUpdate)));


                            string url = string.Empty;
                            if (Application.platform == RuntimePlatform.Android)
                            {
                                string id = "com.longtugame.xxaxc"; //写死
                                url = string.Format("market://details?id={0}", id);
                            }
                            else if (Application.platform == RuntimePlatform.IPhonePlayer)
                            {
                                string id = "1073000645"; //写死
                                url = string.Format("itms-apps://itunes.apple.com/app/id{0}?action=write-review", id);
                            }
                            Patcher.Instance.LogString(string.Format("OpenUrl:{0}", url));
                            OSUtility.OpenUrl(url);  //跳转到商店

                            yield return(null);

                            yield return(null);
                        }
#else
                        // 非Kakao平台
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasFatalErrorNeedReinstall),
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateStatus_BeginUpdate)));

                        Patcher.Instance.UpdateExit();
                        EntryPoint.ExitGame();
                        yield break;
#endif
#endif
                    }
                    else if (retCode == UpdateRetCode.pack_file_broken)                                       //某些安卓机型上出现解包错误,重启app继续更新即可
                    {
                        LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败

                        _HotUpdateViewer.SetCircle(false);
                        CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OK,
                                                          updateInfo.strUpdateInfo,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError)));

                        {
                            Patcher.Instance.UpdateExit();
#if UNITY_ANDROID
                            AndroidUtil.DoRestart(200);
#else
                            EntryPoint.ExitGame();
#endif
                            yield break;
                        }
                    }
                    else if (retCode != UpdateRetCode.success)               //普通错误处理
                    {
                        CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                        string      msgText    = string.Format("{0} {1}", updateInfo.strUpdateInfo, retCode.ToString());

                        _HotUpdateViewer.SetCircle(false);
                        yield return(new WaitForUserClick(MessageBoxStyle.MB_OkCancel,
                                                          msgText,
                                                          UpdateInfoUtil.GetStateString(UPDATE_STATE.UpdateString_HasError)));

                        if (WaitForUserClick.RetCode == 0)
                        {
#if !UNITY_EDITOR
                            LTPlatformBase.ShareInstance().SetBreakPoint(SDK.POINT_STATE.Game_Check_Update_Fail); //平台SDK打点:检查更新失败
                            Patcher.Instance.UpdateExit();
                            EntryPoint.ExitGame();
                            yield break;
#else
                            retCode = UpdateRetCode.success;       //走Phase3
                            break;
#endif
                        }
                        else
                        {
                            UpdateInfoUtil.SetCanPlay(false);    //重试
                        }
                    }
                    else                   //成功
                    {
                        break;
                    }
                } while (true);
            }

            Patcher.Instance.ReleasePackages();

            //第三阶段,下载服务器列表
            if (retCode == UpdateRetCode.success)
            {
                _HotUpdateViewer.SetCircle(false);
                _HotUpdateViewer.PrepareEnterGame();
                //_HotUpdateViewer.SetInstallPercent(-1.0f);

                //yield return new WaitForSeconds(0.2f);

                float progress = 0f;
                float count    = 0;
                foreach (var item in Patcher.UpdateCoroutinePhase3())
                {
                    CUpdateInfo updateInfo = UpdateInfoUtil.GetUpdateInfo();
                    _HotUpdateViewer.SetPartProgress(updateInfo.curUpdateProgress);
                    _HotUpdateViewer.SetAllProgress(updateInfo.totalUpdateProgress);
                    _HotUpdateViewer.SetDesc(updateInfo.strUpdateInfo);
                    _HotUpdateViewer.SetCurrentVersion(updateInfo.curVersion);
                    _HotUpdateViewer.SetServerVersion(updateInfo.serverVersion);

                    //新UI
                    _HotUpdateViewer.SetInstallInfo(updateInfo.strUpdateInfo);
                    _HotUpdateViewer.SetEnterGameTips(updateInfo.strUpdateInfo);
                    //模拟进度条
                    _HotUpdateViewer.SetEnterGameProgress(progress);
                    float maxProgress = (count < 2) ? 0.5f : 1f;
                    progress = UnityEngine.Random.Range(progress, maxProgress);
                    count++;

                    yield return(null);

                    if (item is UpdateRetCode)
                    {
                        retCode = (UpdateRetCode)item;
                        break;
                    }
                    else
                    {
                        yield return(item);
                    }
                }

                if (retCode != UpdateRetCode.success)
                {
                    yield return(new WaitForSeconds(1.0f));

                    UpdateInfoUtil.SetCanPlay(false);
                }
                else
                {
                    _HotUpdateViewer.SetEnterGameProgress(1f);
                    yield return(new WaitForSeconds(0.3f));

                    UpdateInfoUtil.SetCanPlay(true);
                }
            }
        }

        Patcher.Instance.UpdateExit();

        if (UpdateInfoUtil.GetUpdateInfo().bCanPlay)
        {
            _IsUpdateSucceed = true;
            yield return(null);
        }

        //yield return new WaitForSeconds(2.0f);
    }