using UnityEngine; using System; using System.Net; using System.IO; using System.Text; using System.Threading; using System.Collections; using System.Collections.Generic; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text.RegularExpressions; using GameCore; namespace ResUpdate { /// /// 下载进度 /// public class DownLoadProgress { /// /// 已经下载的大小:Byte /// public long Size { get; private set; } /// /// 已经下载的大小:KB /// public float SizeKB { get { return 1f * Size / 1024; } } /// /// 已经下载的大小:MB /// public float SizeMB { get { return 1f * Size / 1024/1024; } } /// /// 需要下载的大小:Byte /// public long TotalSize { get; private set; } /// /// 需要下载的大小:KB /// public float TotalSizeKB { get { return 1f * TotalSize / 1024; } } /// /// 需要下载的大小:MB /// public float TotalSizeMB { get { return 1f * TotalSize / 1024/1024; } } /// /// 进度 /// public float Progress { get { if (TotalSize == 0) return 1f; return Mathf.Clamp01(1f * Size / TotalSize); } } /// /// 下载速度 /// public float LoadSpeed { get; private set; } /// /// 更新进度 /// /// 已经下载的大小 /// 需要下载的大小 internal void UpdateProgress(long size, long totalSize,float speed) { this.Size = size; this.TotalSize = totalSize; this.LoadSpeed = speed; } /// /// 重置 /// internal void Reset() { this.Size = 0; this.TotalSize = 0; } } /// /// 资源下载器 /// public class ResourceDownloadManager : UnitySingleton { /// /// 下载更新间隔 /// const float DOWNLOAD_UPDATE_INTERVAL = 0.05f; /// /// 下载线程数量 /// const int MAX_DOWNLOAD_THREADS_COUNT = 3; /// /// 线程下载器池 /// ObjectPool downloadRequestPool = new ObjectPool(l=>l.Init(), l => l.Reset()); /// /// 线程下载器 /// List downloadRequestList = new List(); /// /// 下载完成的数据 /// Dictionary finishedRequest = new Dictionary(); /// /// 当前正在下载的数量 /// int curDownloadingCount; /// /// 当前网络状态 /// NetworkReachability curNetworkStatus = NetworkReachability.NotReachable; /// /// 下载URL /// public string downloadURL { get; set; } /// /// 是否允许从数据流量下载 /// public bool allowDowloadFromWWAN { get; set; } void Update() { UpdateDownLoadList(); } /// /// 更新下载列表 /// void UpdateDownLoadList() { if (downloadRequestList.Count == 0)return; UpdateCurNetworkStatus(); ProcessDownloadList(); } /// /// 处理下载列表 /// void ProcessDownloadList() { var count = Mathf.Min(MAX_DOWNLOAD_THREADS_COUNT, downloadRequestList.Count); var i = curDownloadingCount; for (; i < count; ++i) { downloadRequestList[i].Start(); curDownloadingCount++; } for (i = 0; i < curDownloadingCount; ) { var downloadRequest = downloadRequestList[i]; if (downloadRequest.downLoadState == DownloadState.Finished) { finishedRequest.Add(downloadRequest.fileName, downloadRequest.isSuccess); downloadRequestList.RemoveAt(i); curDownloadingCount--; downloadRequest.UpdateCallBack(); downloadRequest.FinishCallback(); downloadRequestPool.Release(downloadRequest); } else { downloadRequest.UpdateCallBack(); ++i; } } } /// /// 校验结果 /// /// /// /// /// /// public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { bool isOk = true; // If there are errors in the certificate chain, // look at each error to determine the cause. if (errors != SslPolicyErrors.None) { for (int i = 0; i < chain.ChainStatus.Length; i++) { if (chain.ChainStatus[i].Status == X509ChainStatusFlags.RevocationStatusUnknown) { continue; } chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; bool chainIsValid = chain.Build((X509Certificate2)certificate); if (!chainIsValid) { isOk = false; break; } } } return isOk; } /// /// 开始下载文件 /// /// 文件名 /// 下载地址 /// 保存的文件夹 /// 文件大小 /// 文件CRC /// 完成回调 /// 请求参数 public void StartDownload(string file, string url, string saveDirectory, long size, string crc,Action progressAction=null , Action finishAction = null, string postContent = "") { if (FindInDownLoadList(file) != -1) { return; } if (finishedRequest.ContainsKey(file)) { if (BaseLogger.isDebug) Debug.Log(string.Format("Re download file: {0}.", file)); finishedRequest.Remove(file); } var downloadRequest = downloadRequestPool.Get(); var stringBuilder = new StringBuilder(); var savePath = stringBuilder.Append(UpdateConfigs.PersistentDataPath).Append(saveDirectory).Append(file).ToString(); downloadRequest.Init(file, url, savePath, size, crc,progressAction, finishAction, postContent); downloadRequestList.Add(downloadRequest); } /// /// 开始下载文件 /// /// /// /// /// /// public void StartDownload(string file, string url, string saveDirectory, Action progressAction = null, Action finishAction = null, string postContent = "") { if (FindInDownLoadList(file) != -1) { return; } if (finishedRequest.ContainsKey(file)) { if (BaseLogger.isDebug) Debug.Log(string.Format("Re download file: {0}.", file)); finishedRequest.Remove(file); } var downloadRequest = downloadRequestPool.Get(); var stringBuilder = new StringBuilder(); var savePath = stringBuilder.Append(UpdateConfigs.PersistentDataPath).Append(saveDirectory).Append(file).ToString(); downloadRequest.Init(file, url, savePath,progressAction,finishAction, postContent); downloadRequestList.Add(downloadRequest); } /// /// 是否下载完成 /// /// 文件名 /// public bool IsFinishDownload(string file) { return finishedRequest.ContainsKey(file); } /// /// 是否下载成功 /// /// 文件名 /// public bool IsDownloadSuccess(string file) { bool isSuccess = false; finishedRequest.TryGetValue(file, out isSuccess); return isSuccess; } /// /// 是否在下载中 /// /// 文件名 /// public int FindInDownLoadList(string file) { var count = downloadRequestList.Count; for (var i = 0; i < count; ++i) { if (downloadRequestList[i].fileName == file) { return i; } } return -1; } /// /// 网络是否可用 /// public bool IsNetworkReachable { get { return ((allowDowloadFromWWAN && curNetworkStatus == UnityEngine.NetworkReachability.ReachableViaCarrierDataNetwork) || curNetworkStatus == UnityEngine.NetworkReachability.ReachableViaLocalAreaNetwork); } } /// /// 更新网络状态 /// void UpdateCurNetworkStatus() { NetworkReachability state = Application.internetReachability; if (curNetworkStatus != state) { curNetworkStatus = state; if (BaseLogger.isDebug) Debug.Log(string.Format("curNetworkStatus changed:{0}", curNetworkStatus)); if (!IsNetworkReachable) { ClearDownloadRequestList(); } } } /// /// 清理下载列表 /// void ClearDownloadRequestList() { var count = downloadRequestList.Count; for (var i = curDownloadingCount; i < count; i++) { var downloadRequest = downloadRequestList[i]; downloadRequest.FinishCallback(); downloadRequestPool.Release(downloadRequest); } downloadRequestList.RemoveRange(curDownloadingCount, count - curDownloadingCount); if (BaseLogger.isDebug) BaseLogger.Log("Remove all waiting download file"); } } }