diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs index b6b8745..8dc6d18 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/DownloadSystem.cs @@ -15,7 +15,15 @@ namespace YooAsset private static readonly Dictionary _downloaderDic = new Dictionary(); private static readonly List _removeList = new List(100); private static readonly Dictionary _cachedHashList = new Dictionary(1000); + private static int _breakpointResumeFileSize; + /// + /// 初始化 + /// + public static void Initialize(int breakpointResumeFileSize) + { + _breakpointResumeFileSize = breakpointResumeFileSize; + } /// /// 更新所有下载器 @@ -39,6 +47,21 @@ namespace YooAsset } } + /// + /// 销毁所有下载器 + /// + public static void DestroyAll() + { + foreach (var valuePair in _downloaderDic) + { + var downloader = valuePair.Value; + downloader.Abort(); + } + _downloaderDic.Clear(); + YooLogger.Log("DownloadSystem destroy all !"); + } + + /// /// 开始下载资源文件 /// 注意:只有第一次请求的参数才是有效的 @@ -52,18 +75,21 @@ namespace YooAsset } // 如果资源已经缓存 - if(ContainsVerifyFile(bundleInfo.Hash)) + if (ContainsVerifyFile(bundleInfo.Hash)) { - var newDownloader = new FileDownloader(bundleInfo); - newDownloader.SetDone(); - return newDownloader; + var tempDownloader = new TempDownloader(bundleInfo); + return tempDownloader; } // 创建新的下载器 { YooLogger.Log($"Beginning to download file : {bundleInfo.BundleName} URL : {bundleInfo.RemoteMainURL}"); FileUtility.CreateFileDirectory(bundleInfo.LocalPath); - var newDownloader = new HttpDownloader(bundleInfo); + DownloaderBase newDownloader; + if (bundleInfo.SizeBytes >= _breakpointResumeFileSize) + newDownloader = new HttpDownloader(bundleInfo); + else + newDownloader = new FileDownloader(bundleInfo); newDownloader.SendRequest(failedTryAgain, timeout); _downloaderDic.Add(bundleInfo.Hash, newDownloader); return newDownloader; diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta new file mode 100644 index 0000000..1b00904 --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a82eeb6a47cd02c4cb38e851c8ed8784 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloaderBase.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs similarity index 91% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloaderBase.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs index 359eec3..664e9e0 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/DownloaderBase.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs @@ -44,11 +44,11 @@ namespace YooAsset } - internal DownloaderBase(BundleInfo bundleInfo) + public DownloaderBase(BundleInfo bundleInfo) { _bundleInfo = bundleInfo; } - internal void SendRequest(int failedTryAgain, int timeout) + public void SendRequest(int failedTryAgain, int timeout) { if (string.IsNullOrEmpty(_bundleInfo.LocalPath)) throw new System.ArgumentNullException(); @@ -60,12 +60,9 @@ namespace YooAsset _steps = ESteps.CreateDownload; } } - internal void SetDone() - { - _steps = ESteps.Succeed; - } - internal abstract void Update(); - + public abstract void Update(); + public abstract void Abort(); + /// /// 获取网络请求地址 /// diff --git a/Assets/YooAsset/Runtime/DownloadSystem/DownloaderBase.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/DownloaderBase.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/DownloaderBase.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/FileDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs similarity index 93% rename from Assets/YooAsset/Runtime/DownloadSystem/FileDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs index b23913a..8b212f2 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/FileDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs @@ -19,10 +19,10 @@ namespace YooAsset private float _tryAgainTimer; - internal FileDownloader(BundleInfo bundleInfo) : base(bundleInfo) + public FileDownloader(BundleInfo bundleInfo) : base(bundleInfo) { } - internal override void Update() + public override void Update() { if (_steps == ESteps.None) return; @@ -123,6 +123,16 @@ namespace YooAsset } } } + public override void Abort() + { + if (IsDone() == false) + { + _steps = ESteps.Failed; + _lastError = "user abort"; + DisposeWebRequest(); + } + } + private void CheckTimeout() { // 注意:在连续时间段内无新增下载数据及判定为超时 diff --git a/Assets/YooAsset/Runtime/DownloadSystem/FileDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/FileDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/FileDownloader.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/HttpDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/HttpDownloader.cs similarity index 72% rename from Assets/YooAsset/Runtime/DownloadSystem/HttpDownloader.cs rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/HttpDownloader.cs index 652c152..7f46fe7 100644 --- a/Assets/YooAsset/Runtime/DownloadSystem/HttpDownloader.cs +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/HttpDownloader.cs @@ -18,6 +18,7 @@ namespace YooAsset private const int BufferSize = 1042 * 4; private Thread _thread; + private bool _running = true; private string _url; private string _savePath; private string _fileHash; @@ -30,11 +31,6 @@ namespace YooAsset /// public bool IsDone = false; - /// - /// 下载结果(成功或失败) - /// - public bool Result = true; - /// /// 错误日志 /// @@ -69,51 +65,57 @@ namespace YooAsset } /// - /// 销毁下载器 + /// 中断下载线程 /// - public void Dispose() + public void Abort() { - if (_thread != null) - { - _thread.Abort(); - _thread = null; - } + _running = false; } + /// + /// 下载结果 + /// + public bool HasError() + { + if (string.IsNullOrEmpty(Error)) + return false; + else + return true; + } private void ThreadRun() { long fileTotalSize = _fileSize; FileStream fileStream = null; - Stream webStream = null; - HttpWebResponse fileResponse = null; + HttpWebResponse webResponse = null; + Stream responseStream = null; try { // 创建文件流 fileStream = new FileStream(_savePath, FileMode.OpenOrCreate, FileAccess.Write); - long fileLength = fileStream.Length - 1; + long fileLength = fileStream.Length; // 创建HTTP下载请求 - HttpWebRequest fileRequest = WebRequest.Create(_url) as HttpWebRequest; - fileRequest.Timeout = _timeout * 1000; - fileRequest.ProtocolVersion = HttpVersion.Version10; + HttpWebRequest webRequest = WebRequest.Create(_url) as HttpWebRequest; + webRequest.Timeout = _timeout * 1000; + webRequest.ProtocolVersion = HttpVersion.Version10; if (fileLength > 0) { // 注意:设置远端请求文件的起始位置 - fileRequest.AddRange(fileLength); + webRequest.AddRange(fileLength); // 注意:设置本地文件流的起始位置 - fileStream.Seek(-1, SeekOrigin.End); + fileStream.Seek(fileLength, SeekOrigin.Begin); } // 读取下载数据并保存到文件 - fileResponse = fileRequest.GetResponse() as HttpWebResponse; - webStream = fileResponse.GetResponseStream(); + webResponse = webRequest.GetResponse() as HttpWebResponse; + responseStream = webResponse.GetResponseStream(); byte[] buffer = new byte[BufferSize]; - while (true) + while (_running) { - int length = webStream.Read(buffer, 0, buffer.Length); + int length = responseStream.Read(buffer, 0, buffer.Length); if (length <= 0) break; @@ -129,20 +131,20 @@ namespace YooAsset } catch (Exception e) { - Result = false; Error = e.Message; } finally { - if (webStream != null) + if (responseStream != null) { - webStream.Close(); - webStream.Dispose(); + responseStream.Close(); + responseStream.Dispose(); } - if (fileResponse != null) + if (webResponse != null) { - fileResponse.Close(); + webResponse.Close(); + webResponse.Dispose(); } if (fileStream != null) @@ -152,17 +154,20 @@ namespace YooAsset } // 验证下载文件完整性 - if (Result) + if (DownloadedBytes == (ulong)_fileSize) { bool verfiyResult = DownloadSystem.CheckContentIntegrity(_savePath, _fileSize, _fileCRC); if (verfiyResult == false) { - Result = false; - Error = $"Verify file content failed : {_fileHash}"; + Error = $"Verify download content failed : {_fileHash}"; if (File.Exists(_savePath)) File.Delete(_savePath); } } + else + { + Error = $"Download content is incomplete : {_fileHash}"; + } IsDone = true; } @@ -173,10 +178,10 @@ namespace YooAsset private ThreadDownloader _threadDownloader; private float _tryAgainTimer; - internal HttpDownloader(BundleInfo bundleInfo) : base(bundleInfo) + public HttpDownloader(BundleInfo bundleInfo) : base(bundleInfo) { } - internal override void Update() + public override void Update() { if (_steps == ESteps.None) return; @@ -203,12 +208,7 @@ namespace YooAsset if (_threadDownloader.IsDone == false) return; - if (_threadDownloader.Result) - { - DownloadSystem.CacheVerifyFile(_bundleInfo.Hash, _bundleInfo.BundleName); - _steps = ESteps.Succeed; - } - else + if (_threadDownloader.HasError()) { _lastError = _threadDownloader.Error; ReportError(); @@ -219,9 +219,11 @@ namespace YooAsset else _steps = ESteps.Failed; } - - // 释放下载器 - _threadDownloader.Dispose(); + else + { + DownloadSystem.CacheVerifyFile(_bundleInfo.Hash, _bundleInfo.BundleName); + _steps = ESteps.Succeed; + } } // 重新尝试下载 @@ -236,5 +238,18 @@ namespace YooAsset } } } + public override void Abort() + { + if(IsDone() == false) + { + _steps = ESteps.Failed; + _lastError = "user abort"; + if (_threadDownloader != null) + { + _threadDownloader.Abort(); + _threadDownloader = null; + } + } + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/HttpDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/HttpDownloader.cs.meta similarity index 100% rename from Assets/YooAsset/Runtime/DownloadSystem/HttpDownloader.cs.meta rename to Assets/YooAsset/Runtime/DownloadSystem/Downloader/HttpDownloader.cs.meta diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs new file mode 100644 index 0000000..aafdb89 --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs @@ -0,0 +1,20 @@ + +namespace YooAsset +{ + internal sealed class TempDownloader : DownloaderBase + { + public TempDownloader(BundleInfo bundleInfo) : base(bundleInfo) + { + _downloadProgress = 1f; + _downloadedBytes = (ulong)bundleInfo.SizeBytes; + _steps = ESteps.Succeed; + } + + public override void Update() + { + } + public override void Abort() + { + } + } +} \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs.meta b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs.meta new file mode 100644 index 0000000..a225b15 --- /dev/null +++ b/Assets/YooAsset/Runtime/DownloadSystem/Downloader/TempDownloader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c7907ead85e2f94786308b28c37a8aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: