/// <summary> /// 根据检测模式检测已下载的文件. /// </summary> /// <returns><c>true</c>, OK, <c>false</c> NG.</returns> /// <param name="iTarget">目标信息.</param> /// <param name="iDownloadFileFullPath">已经下载到本地的路径.</param> private bool CheckFileByCheckMode(DownloadTargetInfo iTarget, string iDownloadFileFullPath) { if (File.Exists(iDownloadFileFullPath) == false) { return(false); } bool isCheckOK = true; switch (UploadList.GetInstance().CheckMode) { case TCheckMode.Unity3d_Hash128: { this.Info("CheckFileByCheckMode()::The Unity3d_Hash128 of check mode has not been supported yet!!!"); isCheckOK = false; } break; case TCheckMode.Custom_Md5: { string md5 = UploadList.GetFileMD5(iDownloadFileFullPath); if ((true == string.IsNullOrEmpty(md5)) || (false == md5.Equals(iTarget.CheckCode))) { isCheckOK = false; } } break; default: break; } return(isCheckOK); }
/// <summary> /// 下载完成. /// </summary> /// <param name="iTargetID">目标ID.</param> /// <param name="iFileType">文件类型.</param> public void DownloadCompleted(string iTargetID, TUploadFileType iFileType) { lock (_targetUpdateLock) { DownloadTargetInfo downloadInfo = null; if (this.isTargetExist(iTargetID, iFileType, out downloadInfo) == true) { if (downloadInfo == null) { return; } downloadInfo.Downloaded = true; if (this._progressCounter != null) { this._progressCounter.UpdateCompletedCount(); long dataSize = (string.IsNullOrEmpty(downloadInfo.DataSize) == true) ? 0 : Convert.ToInt64(downloadInfo.DataSize); this._progressCounter.UpdateCompletedDataSize(dataSize); this.Info("DownloadCompleted()::Count({0}/{1}) DataSize({2}/{3})", this._progressCounter.DidCount, this._progressCounter.TotalCount, this._progressCounter.DidDatasize, this._progressCounter.TotalDatasize); } } } }
/// <summary> /// 判断目标存不存在. /// </summary> /// <returns><c>true</c>, 存在, <c>false</c> 不存在.</returns> /// <param name="iBundleId">BundleID.</param> /// <param name="iFileType">文件类型.</param> /// <param name="iTarget">下载目标信息.</param> public bool isTargetExist(string iBundleId, TUploadFileType iFileType, out DownloadTargetInfo iTarget) { iTarget = null; if (string.IsNullOrEmpty(iBundleId) == true) { return(false); } DownloadTargetInfo[] targets = this.Targets .Where(o => ( (iBundleId.Equals(o.ID) == true) && (iFileType == o.FileType))) .OrderByDescending(o => o.No) .ToArray(); if ((targets == null) || (targets.Length <= 0)) { return(false); } if (1 != targets.Length) { this.Warning("isTargetExist()::There is duplicate id exist in download list!!!(Bundle ID:{0} FileType:{1})", iBundleId, iFileType); } iTarget = targets [0]; return(true); }
/// <summary> /// 添加对象. /// </summary> /// <param name="iTarget">上传目标.</param> public void AddTarget(UploadItem iTarget) { DownloadTargetInfo target = null; if (false == isTargetExist(iTarget.ID, iTarget.FileType, out target)) { target = new DownloadTargetInfo(); this.Targets.Add(target); target.No = iTarget.No; target.ID = iTarget.ID; target.BundleType = iTarget.BundleType; target.FileType = iTarget.FileType; target.DataSize = iTarget.DataSize; target.CheckCode = iTarget.CheckCode; target.Downloaded = false; this.Info("AddTarget()::New:{0}", iTarget.toString()); } else { // 变更的场合 if (false == iTarget.CheckCode.Equals(target.CheckCode)) { target.DataSize = iTarget.DataSize; target.CheckCode = iTarget.CheckCode; target.Downloaded = false; this.Info("AddTarget()::Changed:{0}", iTarget.toString()); } } }
/// <summary> /// 初始化. /// </summary> /// <param name="iTarget">下载目标.</param> /// <param name="iOnStart">开始事件委托.</param> /// <param name="iOnSuccessed">成功事件委托.</param> /// <param name="iOnFailed">失败事件委托.</param> /// <param name="iLocalSave">本地保存标志位.</param> /// <param name="iType">下载对象类型.</param> public void Init( DownloadTargetInfo iTarget, OnStart iOnStart, OnSuccessed iOnSuccessed, OnFailed iOnFailed) { this._target = iTarget; this.DownloadBaseUrl = ServersConf.GetBundleDownloadBaseURL(iTarget); this.FileName = UploadList.GetLocalBundleFileName(iTarget.ID, iTarget.FileType); this.FullFileName = string.Format("{0}/{1}", this.DownloadDir, this.FileName); this.onStart = iOnStart; this.onSuccessed = iOnSuccessed; this.onFailed = iOnFailed; this.Retries = ServersConf.GetInstance().NetRetries; this.TimeOut = ServersConf.GetInstance().NetTimeOut * 1000; if (TBundleType.Scene != iTarget.BundleType) { this.TargetType = TargetType.BundleOfNormal; } else { this.TargetType = TargetType.BundleOfScenes; } // 检查目录 if (Directory.Exists(this.DownloadDir) == false) { Directory.CreateDirectory(this.DownloadDir); } }
/// <summary> /// 下载失败回调函数. /// </summary> /// <param name="iDownloadInfo">下载信息.</param> /// <param name="iIsManifest">Manifest文件标志位.</param> /// <param name="iErrors">错误信息.</param> public void OnDownloadFail(DownloaderBase iDownloader, DownloadTargetInfo iDownloadInfo, bool iIsManifest, List <ErrorDetail> iErrors) { // 线程安全:添加错误信息至列表 lock (_downloaderErrorLock) { string errsStr = null; foreach (ErrorDetail error in iErrors) { if (string.IsNullOrEmpty(errsStr) == true) { errsStr = string.Format("Type:{0} State:{1} Detail:{2} Retries:{3}", error.Type.ToString(), error.State.ToString(), error.Detail, error.Retries.ToString()); } else { errsStr = string.Format("{0} \n Type:{1} State:{2} Detail:{3} Retries:{4}", errsStr, error.Type.ToString(), error.State.ToString(), error.Detail, error.Retries.ToString()); } } this.Error("OnDownloadFail()::Download Failed!!! {0} \n Detail:{1}", iDownloadInfo.toString(), errsStr); this._errors.AddRange(iErrors); this._State = TRunState.Error; if (iDownloader != null) { iDownloader.Dispose(); GC.Collect(); } } }
/// <summary> /// 创建下载器. /// </summary> /// <returns>下载器.</returns> /// <param name="iTarget">目标信息.</param> private DownloaderBase CreateDownloader(DownloadTargetInfo iTarget) { DownloaderBase downloader = null; TDownloadWay downloadWay = ServersConf.GetInstance().DownloadWay; switch (downloadWay) { case TDownloadWay.WWW: { downloader = WWWDownloader.Create( iTarget, OnStartDownload, OnDownloadSuccessed, OnDownloadFail); } break; case TDownloadWay.None: case TDownloadWay.Http: default: { downloader = HttpDownloader.Create( iTarget, OnStartDownload, OnDownloadSuccessed, OnDownloadFail); } break; } return(downloader); }
/// <summary> /// 取得Bundle全路径名. /// </summary> /// <returns>Bundle全路径名.</returns> /// <param name="iBundleId">BundleId.</param> /// <param name="iFileType">文件类型.</param> public string GetBundleFullPath( string iBundleId, TUploadFileType iFileType = TUploadFileType.Bundle) { DownloadTargetInfo targetInfo = null; if (isTargetExist(iBundleId, iFileType, out targetInfo) == false) { this.Error("GetBundleFullPath()::This bundles is not exist!!!({BundleId:{0} FileType:{1})", iBundleId, iFileType); return(null); } if (targetInfo == null) { return(null); } string fileName = UploadList.GetLocalBundleFileName(iBundleId, targetInfo.FileType); if (string.IsNullOrEmpty(fileName) == true) { return(null); } string fileFullPath = null; switch (targetInfo.BundleType) { case TBundleType.Normal: { fileFullPath = string.Format("{0}/{1}", ServersConf.BundlesDirOfNormal, fileName); } break; case TBundleType.Scene: { fileFullPath = string.Format("{0}/{1}", ServersConf.BundlesDirOfScenes, fileName); } break; default: { fileFullPath = string.Format("{0}/{1}", ServersConf.BundlesDir, fileName); } break; } return(fileFullPath); }
/// <summary> /// 创建Downloader. /// </summary> /// <param name="iTargetInfo">下载目标.</param> /// <param name="iOnStart">开始委托回调.</param> /// <param name="iOnSuccessed">成功委托回调.</param> /// <param name="iOnFailed">失败委托回调.</param> /// <param name="iRetries">重下载次数.</param> /// <param name="iTimeOut">超时时间(单位:秒).</param> public static WWWDownloader Create( DownloadTargetInfo iTargetInfo, OnStart iOnStart, OnSuccessed iOnSuccessed, OnFailed iOnFailed) { WWWDownloader downloader = new WWWDownloader(); if (downloader != null) { // 初始化 downloader.Init(iTargetInfo, iOnStart, iOnSuccessed, iOnFailed); return(downloader); } else { UtilsLog.Error("Create", "Downloader Create failed!!"); return(null); } }
/// <summary> /// 下载成功回调函数. /// </summary> /// <param name="iDownloadInfo">下载信息.</param> /// <param name="iRetries">重试次数.</param> public void OnDownloadSuccessed(DownloaderBase iDownloader, DownloadTargetInfo iDownloadInfo, int iRetries) { this.Info("OnDownloadSuccessed()::Download Successed. {0} Retries:{1}", iDownloadInfo.toString(), iRetries); DownloadList.GetInstance().DownloadCompleted(iDownloadInfo.ID, iDownloadInfo.FileType); if (true == iDownloadInfo.Downloaded) { // 文件拷贝 iDownloadInfo.CopyTargetWhenDownloadCompleted(); if (iDownloader != null) { iDownloader.Dispose(); GC.Collect(); } lock (_downloaderCountLock) { --this.DownloaderCount; } } }
/// <summary> /// 判断目标存不存在. /// </summary> /// <returns><c>true</c>, 存在, <c>false</c> 不存在.</returns> /// <param name="iBundleId">BundleID.</param> /// <param name="iTarget">下载目标信息.</param> public bool isTargetExist(string iBundleId, out DownloadTargetInfo iTarget) { return(isTargetExist(iBundleId, TUploadFileType.Bundle, out iTarget)); }