using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine; using UnityEngine.Events; namespace AssetUpdate { public abstract class AssetDownloadAction : IAssetAsyncAction { //public UnityWebRequest currentRequest { get; private set; } protected Dictionary _assetPathInfo; private BinaryFormatter _formatter; public AssetUpdateManager.AssetUpdateError error; public List downloadList { get; private set; } public int current { get; private set; } public string uriHeader { get; private set; } public AssetUpdateDownloader downloader { get; private set; } public long totalSize { get; private set; } public long completeSize { get; private set; } public bool UpdateTimeout() { return current >= downloadList.Count || error != AssetUpdateManager.AssetUpdateError.Success; } public void Dispose() { if (downloader != null) downloader.Dispose(); } public void Start(string uri, List list) { uriHeader = uri; downloadList = list; totalSize = downloadList.Aggregate(0, (current1, t) => current1 + t.fileSize); var filePath = AssetConst.persistentDataPath.Open(AssetConst.pathFile + AssetConst.bytesExtension); _formatter = new BinaryFormatter(); if (File.Exists(filePath)) try { using (var fs = File.OpenRead(filePath)) { _assetPathInfo = _formatter.Deserialize(fs) as Dictionary; } } catch (Exception e) { Debug.LogError(e); } if (_assetPathInfo == null) _assetPathInfo = new Dictionary(); if (downloadList.Count > 0) { current = -1; CreateConfirmUi(OnDownloadConfirm); } } public long GetCurrentBytes() { return completeSize + (downloader == null ? 0 : downloader.finishedSize); } // public float GetCurrentProgress() // { // return downloader == null ? 1f : downloader.progress; // } protected abstract void CreateConfirmUi(UnityAction callback); // 项目相关功能 protected abstract void CreateDownloadUi(); // 项目相关功能 protected abstract void RemoveDownloadUi(); private void OnDownloadConfirm(bool isConfirm) { if (isConfirm) { CreateDownloadUi(); StartNextItem(); } else { error = AssetUpdateManager.AssetUpdateError.UserCancel; } } private void StartNextItem() { current++; if (current < downloadList.Count) { var data = downloadList[current]; var uri = uriHeader.Open(data.version.ToString()).Open(data.name + AssetConst.bundleVariant); var filePath = AssetConst.GetPersistBundle(data.name + AssetConst.bundleVariant); downloader = new AssetUpdateDownloader(uri, filePath) {onComplete = OnWebRequestComplete}; downloader.Start(); } else { ShowComplete(); RemoveDownloadUi(); } } protected abstract void ShowComplete(); private void OnWebRequestComplete(AssetUpdateDownloader loader) { error = downloader.error; var downloadSize = downloader.finishedSize; // 移除当前记录,防止获得进度时会报参数错误 downloader = null; if (error == AssetUpdateManager.AssetUpdateError.Success) { var data = downloadList[current]; var filePath = AssetConst.GetPersistBundle(data.name + AssetConst.bundleVariant); if (!File.Exists(filePath)) { error = AssetUpdateManager.AssetUpdateError.FileCreateError; } else { // Hash校验 if (AssetUtils.GetFileMd5(filePath) != data.md5) { Debug.LogError(string.Format("Hash check on {0} didn't match! Restart the download!", data.name)); // 网络没有问题,回滚文件再次下载 current--; StartNextItem(); // error = AssetUpdateManager.AssetUpdateError.FileCreateError; } else { completeSize += downloadSize; // 保存下载数据 _assetPathInfo[data.name] = data.md5; filePath = AssetConst.persistentDataPath.Open(AssetConst.pathFile + AssetConst.bytesExtension); using (var fs = File.Create(filePath)) { _formatter.Serialize(fs, _assetPathInfo); } StartNextItem(); } } } else { Debug.LogError(string.Format("Failed to download file {0}!", downloadList[current].name)); } } } }